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.