Map libraries comparison: Leaflet vs Mapbox GL vs OpenLayers – trends and statistics

When you need to add a map to your application, the first question that pop-ups in your head is “Which map library to use?”. If you start to google, you’ll find out soon that at the moment the Leaflet, Mapbox GL, OpenLayers are the most popular libraries for displaying interactive maps on a web page.

In this article, we want to compare the libraries and check actual trends and statistics. So you can choose the most promising option for you.

We used NPM Trends and Google Trends to get the data and create beautiful visualizations.

Leaflet vs Mapbox GL vs OpenLayers

LeafletMapbox GLOpenLayers
The open-source JS library for interactive maps. A simple interface, great documentation, and a huge community allow you to get results and solve your tasks quickly.
Unfortunately, not developed actively any longer.
Powerful and effective SDK for web maps developed by Mapbox. As Leaflet library creators developed Mapbox GL now, you can see some similarities between 2 libraries. However, Mapbox GL gives you more opportunities, data visualization options and opens the vector maps world for you.Familiar with GIS technologies? Then OpenLayers can be the perfect option for you! The OpenLayers is not only about displaying maps, but also visualizing and analyzing geographical data. It could be a bit more complicated at the beginning but allows you to create more powerful solutions.
Vector maps support
The core functionality of Leaflet doesn’t have vector tiles support. Nevertheless, you can visualize vector tiles by using external plugins. For example, Mapbox GL Leaflet.
Vector maps support
Mapbox is a pioneer in vector maps technologies. The Mapbox Style Specification for vector maps, which is very popular now and used by Geoapify as well, is natively supported by Mapbox GL.
Vector maps support
OpenLayers has native support for vector maps but the ol-mapbox-style plugin is required to create a map with Mapbox Style Specification.
JSFiddle code sampleJSFiddle code sampleJSFiddle code sample

NPM trends for the map libraries

The number of downloads for npm packages gives a great indication of how popular each library is. Here is npm trends statistics for the last 12 month:

npm trends: Leaflet, Mapbox GL, Openlayers

And the charts look really interesting! After absolute leadership Leaflet losing to Mapbox GL in February 2020. In comparison with other map libraries, OpenLayers looks stable. And if we check the statistics for OpenLayers only, we can prove that:

npm trends: OpenLayers

Statistics from GitHub show us how many times a library was “stared”:

GitHub statistics: Leaflet, Mapbox GL, Openlayers

And here we see that Leaflet is 5 times more popular at the moment than Mapbox GL, and 4 times more popular than OpenLayers.

Google Trends for the map libraries

Google search keywords trends are another good measure of popularity. However, here we’ve faced with a problem. While “Leaflet” and “OpenLayers” are unique names, “Mapbox GL” is often googled as “Mapbox”. So we decided to add both “Mapbox GL” and “Mapbox” to give you an overview:

The chart shows that interest in each library more or less stays on the same level. In other hands, statistics by regions provide some interesting results as well:

Map libraries comparison by region

Leaflet leads the keywords list in almost all countries. However, Mapbox/Mapbox GL is popular in China, the United States, Belorus, and Canada. And OpenLayers is in request in South Korea, Croatia, and Finland.

Conclusions

It’s always a matter of taste when you are trying to choose the best from the good ones. Nevertheless, we hope that the numbers and charts we gave you in this article will help you to make the right decision.

Leaflet, Mapbox GL, and OpenLayers code samples

We’ve created code samples to help you develop a custom map for your website. Visit the Geoapify Documentation page to learn how to add a map to your React-, Angular-, or Vue-webapp.

Geoapify offers map tiles that can be used with all the libraries. We provide vector and raster maps of different styles and colors. Learn more about Geoapify Map Tiles.

Angular + Leaflet: step by step tutorial to add a map

This tutorial helps you to create an Angular-based application and add a Leaflet map as a component. In our tutorial, we provide a way to use the Leaflet library without additional components. Moreover, we prepared an Angular-project for you that contains already a component skeleton for the map component.

We use Geoapify map tiles for the tutorial. You can choose between different map styles and colors there. Check the Geoapify Maps Playground that contains Live demo and code samples.

We use Mapbox style specification, which describes how the map is rendered, tile server locations, and provides values for map settings. For example, minimum, and maximal zoom levels.

Before you start

Step 1. Create an Angular project

You can use the Angular project template we’ve prepared for you or create a new one with Angular CLI. The project template contains already a component for a map:

  • Download or clone the GitHub repository
  • Switch to the project folder: cd angular-based-project
  • Run npm install to install libraries and dependencies
  • Run ng serve for a dev server
  • Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Step 2. Display a map with Leaflet

Install Leaflet + Mapbox GL plugin

By default, Leaflet doesn’t support vector tiles and Mapbox Style specifications. Therefore you need to install the Mapbox GL Leaflet plugin together with Leaflet to generate a map from style.json:

npm i leaflet mapbox-gl mapbox-gl-leaflet
Install Leaflet + Mapbox GL types

Type definitions will allow you to utilize Leaflet and Mapbox types in your code. Moreover, some IDEs provide code completion when the types are available:

npm i @types/leaflet @types/mapbox-gl-leaflet -dev
Add Leaflet and Mapbox styles

Leaflet and Mapbox styles are required to render a map and it’s elements correctly. We recommend you to add styles to the angular.json:

"projects": {
    "angular-project": {
      ...
      "architect": {
        "build": {
          "options": {
            ...
            "styles": [
              "src/styles.scss",
              "node_modules/mapbox-gl/dist/mapbox-gl.css",
              "node_modules/leaflet/dist/leaflet.css"
            ],
            "scripts": []
          },
          ...
        }
      }
    }
}

You will need to restart the dev server to apply changes from angular.json.

Add a Leaflet map to an Angular-component

Open MyMapComponent if you use our template or create a new component.

  • Remove placeholder and create ViewChild for the div element. Add ngAfterViewInit() lifecycle hook that is called after Angular has fully initialized a component’s view:
<div class="map-container" #map></div>
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-my-map',
  templateUrl: './my-map.component.html',
  styleUrls: ['./my-map.component.scss']
})
export class MyMapComponent implements OnInit, AfterViewInit {

  @ViewChild('map')
  private mapContainer: ElementRef<HTMLElement>;

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit() {
  }
}
  • Add a Leaflet map to the component:
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import  * as L from 'leaflet';
import 'mapbox-gl-leaflet';

@Component({
  selector: 'app-my-map',
  templateUrl: './my-map.component.html',
  styleUrls: ['./my-map.component.scss']
})
export class MyMapComponent implements OnInit, AfterViewInit {

  private map: L.Map;

  @ViewChild('map')
  private mapContainer: ElementRef<HTMLElement>;

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit() {
    const myAPIKey = "YOUR_API_KEY_HERE";
    const mapStyle = "https://maps.geoapify.com/v1/styles/osm-carto/style.json";

    const initialState = {
      lng: 11,
      lat: 49,
      zoom: 4
    };

    const map = new L.Map(this.mapContainer.nativeElement).setView(
      [initialState.lat, initialState.lng],
      initialState.zoom
    );

    // the attribution is required for the Geoapify Free tariff plan
    map.attributionControl
      .setPrefix("")
      .addAttribution(
        'Powered by <a href="https://www.geoapify.com/" target="_blank">Geoapify</a> | © OpenStreetMap <a href="https://www.openstreetmap.org/copyright" target="_blank">contributors</a>'
      );

    L.mapboxGL({
      style: `${mapStyle}?apiKey=${myAPIKey}`,
      accessToken: "no-token"
    }).addTo(map);
  }
}

Build the application

Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

More code sample

Find more Live demos, JSFiddle samples and Code samples on the Geoapify API Documentation page.

How to call HTTP Get request

All Geoapify APIs work via HTTP Get requests. In this article, we would like to highlight some examples, how to implement HTTP request in your application.

JavaScript: Get request with XMLHttpRequest object

Firstly, one HTTP request example with the XMLHttpRequest object. The XMLHttpRequest object is classical and proved by time way to build HTTP request in JavaScript.

Do not be confused by word “XML” in the name. XMLHttpRequest is very flexible in nature and allows to operate with any data type. Of cause, the method perfectly works with JSON objects as well.

For example, the implementation could look like:

var xmlHttp = new XMLHttpRequest();
xmlHttp.responseType = 'json';
var url = "https://api.geoapify.com/v1/isoline?lat=47.68388118858141&lon=8.614278188654232&type=time&mode=drive&range=2700&api_key=YOUR_API_KEY";
xmlHttp.onreadystatechange = () => {
    if (xmlHttp.readyState === 4) {
        if (xmlHttp.status === 200) {
            // check xmlHttp.responseText here;
            console.log(xmlHttp.response);
        } else {
            console.log(xmlHttp.response);
        }
    }
};
xmlHttp.open("GET", url, true); // true for asynchronous 
xmlHttp.send(null);

JavaScript: fetch() to build HTTP request

Another we-known way to build an HTTP request in JavaScript application is using fetch(). Fetch() provides similar functionality as XMLHttpRequest, but instead of callbacks and a bit complicated API, fetch() returns a promise. Moreover, you can define URI parameters separately as an object. So fetch() allows making your code cleaner and smaller.

For instance, fetch() could look that way in your code:

var url = new URL('https://api.geoapify.com/v1/isoline');

var params = [['lat', '47.68388118858141'], ['lon', '8.614278188654232'], ['mode', 'drive'], ['type', 'time'], ['range', '2700'], ['api_key', 'YOUR_API_KEY']];
url.search = new URLSearchParams(params);

fetch(url).then(response => response.json()).then(data => console.log(data)).catch(err => console.log(err));

Angular: HttpClient

Angular brings new standards into our code and life. The common way to implement HTTP request in Angular is by using HTTPClient.

You just add HttpClient to a class constructor and call get(). However, don’t forget to import HttpClientModule in your module file. The data returned is already in JSON format, you do not need to convert it separately.

// import BrowserModule and HttpClientModule in a module file
constructor(private httpClient: HttpClient, ...) {

}

getData() {
  const url = "https://api.geoapify.com/v1/isoline?lat=47.68388118858141&lon=8.614278188654232&type=time&mode=drive&range=2700&api_key=YOUR_API_KEY";

  this.httpClient.get(url).subscribe(data => {
    // check for returned data
  }, err => {
    // check for error
  });
}

HTTP Request in Terminal

Sometimes it’s useful to call HTTP requests from terminal to check if the functionality works independently from a platform or framework. You can do it with curl, for example:

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET "https://api.geoapify.com/v1/isoline?lat=47.68388118858141&lon=8.614278188654232&type=time&mode=drive&range=2700&api_key=YOUR_API_KEY"

Geoapify APIs to create a map

Our APIs help to create an interactive map with Location Analytics features. For example, your mapping could contain a search field, routing or travel time maps. As our APIs work through HTTP Get requests, they are independent of the framework you use. Register and start using our APIs now, read more about APIs or try them out in Playground.