Leaflet vs OpenLayers vs MapLibre

Leaflet, OpenLayers, and MapLibre GL JS are the three main open-source libraries for maps on the web. All three are free, need no account, and work with OpenStreetMap data. They differ in how they draw the map, which shapes everything else:

  • Leaflet places image tiles and SVG or canvas shapes in the page. It's small and simple, with a large plugin ecosystem.
  • OpenLayers draws everything to a canvas, and reads almost any map format and projection. It's the most complete for GIS work.
  • MapLibre GL JS draws vector tiles on the GPU with WebGL. Maps are smooth to zoom and rotate, can tilt and show 3D terrain, and are styled from a JSON style file. It began as a fork of Mapbox GL JS.

Side by side

Leaflet OpenLayers MapLibre GL JS
Version checked 1.9.4 (2.0 in alpha) 10.11 6.15
License BSD-2-Clause BSD-2-Clause BSD-3-Clause
Draws with Page elements, SVG, canvas Canvas, with WebGL for some layers WebGL
Size of a minimal map, gzipped 44 kB 157 kB, with ol-mapbox-style 285 kB, plus a 147 kB worker
Image tiles Built in Built in Built in, as raster sources
Vector tiles With a plugin Built in Built in
MapLibre and Mapbox style files With the MapLibre GL Leaflet plugin With ol-mapbox-style Built in
Rotation No Yes Yes
Tilt, 3D buildings, terrain No No Yes
Map projections Web Mercator, more with plugins Any, with proj4 Web Mercator and a globe view
GIS formats and services GeoJSON, more with plugins GeoJSON, KML, GPX, GML, WMS, WMTS, and more GeoJSON
Mobile SDKs No No MapLibre Native for iOS and Android

The sizes are Vite production builds of a page with one map and nothing else, checked October 22, 2026. Leaflet's shows image tiles; OpenLayers' and MapLibre's show Mapricot's vector tile style.

The same map in each

Each of these is a complete index.html that shows Mapricot's free vector tiles, which need no key, centered on downtown Portland. Each loads its library from jsDelivr, with no build step. Serve the folder with a web server, such as npx serve or python3 -m http.server, rather than opening the file directly: Leaflet's and MapLibre's maps stay blank when opened from a file, since browsers don't let such a page start MapLibre's web worker.

Leaflet needs the MapLibre GL Leaflet plugin for vector tiles, which brings MapLibre GL JS with it:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Leaflet map</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css">
  </head>
  <body style="margin: 0">
    <div id="map" style="height: 100vh"></div>
    <script type="module">
      import L from "https://cdn.jsdelivr.net/npm/leaflet@1.9.4/+esm";
      import { maplibreGL } from "https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-leaflet@0.1.4/+esm";

      const map = L.map("map").setView([45.5189, -122.6793], 15);
      maplibreGL({ style: "https://tiles.mapricot.com/styles/light.json" }).addTo(map);
    </script>
  </body>
</html>

Leaflet geocoding and routing builds on this page with a search box and routes, and React Leaflet with free vector tiles shows the map in React.

OpenLayers reads the same style file with ol-mapbox-style, and draws the tiles itself:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>OpenLayers map</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@10.11.0/ol.css">
    <script src="https://cdn.jsdelivr.net/npm/ol@10.11.0/dist/ol.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/ol-mapbox-style@13.8.0/dist/olms.js"></script>
  </head>
  <body style="margin: 0">
    <div id="map" style="height: 100vh"></div>
    <script type="module">
      const map = await olms.apply("map", "https://tiles.mapricot.com/styles/light.json");
      map.getView().setCenter(ol.proj.fromLonLat([-122.6793, 45.5189]));
      map.getView().setZoom(15);
    </script>
  </body>
</html>

This page loads OpenLayers' prebuilt script files, which set the globals ol and olms, rather than importing modules with +esm like the others. OpenLayers is split into hundreds of small modules, and jsDelivr bundles each one with its own copy of the modules it uses, so they don't work together: the map draws without labels.

MapLibre GL JS reads the style directly:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>MapLibre map</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@6.15.0/dist/maplibre-gl.css">
  </head>
  <body style="margin: 0">
    <div id="map" style="height: 100vh"></div>
    <script type="module">
      import * as maplibregl from "https://cdn.jsdelivr.net/npm/maplibre-gl@6.15.0/+esm";

      new maplibregl.Map({
        container: "map",
        style: "https://tiles.mapricot.com/styles/light.json",
        center: [-122.6793, 45.5189],
        zoom: 15,
      });
    </script>
  </body>
</html>

Add markers and popups to a MapLibre map builds on this page step by step.

Note the coordinate order: Leaflet takes [latitude, longitude], and MapLibre and OpenLayers' fromLonLat take [longitude, latitude].

Which to choose

Choose Leaflet for a simple map with markers and popups, when page weight matters, or when a Leaflet plugin already does what you need. With image tiles it's the smallest of the three by far. Adding vector tiles through the plugin brings MapLibre's size with it.

Choose OpenLayers for GIS work: projections other than Web Mercator, WMS and WMTS services, KML or GML files, or editing geometry. It draws vector tiles and style files without WebGL.

Choose MapLibre GL JS for vector maps that look polished and move smoothly: custom styles, rotation and tilt, 3D buildings and terrain, and lots of data drawn on the GPU. It's also the natural choice when moving off Mapbox GL JS, since the APIs match. See Migrate from Mapbox GL JS to MapLibre, and MapLibre React for React apps.

Questions

Is Leaflet or MapLibre better? For image tiles and a simple map, Leaflet is smaller and simpler. For vector tiles, custom styles, rotation, or 3D, MapLibre draws them natively and faster.

Is OpenLayers better than Leaflet? For GIS features, yes: projections, formats, and services Leaflet needs plugins for are built into OpenLayers. For a simple map, Leaflet is smaller and quicker to learn.

What's the difference between MapLibre and Mapbox? MapLibre GL JS is the open-source fork of Mapbox GL JS 1.13. Mapbox GL JS 2 and later are proprietary, need a Mapbox token, and bill each map load. MapLibre needs no token and works with any tiles that follow the style format.

Which library works with free map tiles? All three. Mapricot's map tiles are free vector tiles with no key, shown above in each.