Lines & Polylines
Draw styled lines connecting coordinates on the map Each library has its own approach: here's how they compare.
Quick Recommendations
Leaflet — The better fit for simple polylines where L.polyline with [lat, lng] coordinate arrays gets you a styled line in one call.
MapLibre GL JS — The right choice when lines need data-driven width, color, or dash patterns using style expressions on a GeoJSON line layer.
OpenLayers — Makes the most sense when line features need precise geographic measurements or must integrate with OGC vector data sources.
MapTiler SDK — Delivers MapLibre's line layer styling for MapTiler SDK users, with simplified setup.
At a Glance
| Leaflet | MapLibre | OpenLayers | SDK | |
|---|---|---|---|---|
| Coordinates | [lat, lng] | [lng, lat] | fromLonLat([lng, lat]) | [lng, lat] |
| Rendering | DOM + Canvas (2D) | WebGL (GPU, 60fps) | Canvas + WebGL | WebGL (GPU, 60fps) |
| Bundle size | ~42 KB gzipped | ~250 KB gzipped | ~290 KB gzipped (tree-shakeable) | ~280 KB gzipped (includes MapLibre) |
| Learning curve | Easiest (simple API, great tutorials) | Moderate (source/layer model, expressions) | Steepest (projections, OGC standards, verbose API) | Easy (MapLibre API with convenience helpers) |
| 3D support | No native 3D (2D only) | Full: terrain, fill-extrusion, globe, sky | Limited: WebGL layers, no native globe | Full (same as MapLibre) |
| Code lines | 10 | 18 | 21 | 19 |
Code Snippets
Click a library to expand its code. Each snippet shows only the core logic: the scaffold handles HTML boilerplate.
Leaflet10 linesShow code
const map = L.map('map').setView([48.86, 2.35], 13);
L.tileLayer('https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', {
tileSize: 256,
attribution: '© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);
const route = [
[48.8584, 2.2945], [48.8606, 2.3376],
[48.8530, 2.3499], [48.8462, 2.3464]
];
L.polyline(route, { color: '#2196F3', weight: 4, opacity: 0.8 }).addTo(map);MapLibre GL JS18 linesShow code
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/streets-v4/style.json?key=YOUR_MAPTILER_KEY',
center: [14.42, 50.08],
zoom: 12
});
map.on('load', () => {
map.addSource('route', {
type: 'geojson',
data: { type: 'Feature', geometry: { type: 'LineString',
coordinates: [[14.395, 50.095], [14.410, 50.088], [14.425, 50.080], [14.445, 50.075]] } }
});
map.addLayer({
id: 'route-line', type: 'line', source: 'route',
layout: { 'line-join': 'round', 'line-cap': 'round' },
paint: { 'line-color': '#2196F3', 'line-width': 4 }
});
});OpenLayers21 linesShow code
var route = new ol.Feature({
geometry: new ol.geom.LineString([
ol.proj.fromLonLat([2.3522, 48.8566]),
ol.proj.fromLonLat([2.2945, 48.8584]),
ol.proj.fromLonLat([2.3272, 48.8606])
])
});
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({ features: [route] }),
style: new ol.style.Style({
stroke: new ol.style.Stroke({ color: '#e63946', width: 4 })
})
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', attributions: '© <a href="https://www.maptiler.com/copyright/">MapTiler</a>' }) }),
vectorLayer
],
view: new ol.View({ center: ol.proj.fromLonLat([2.32, 48.86]), zoom: 14 })
});MapTiler SDK19 linesShow code
maptilersdk.config.apiKey = 'YOUR_MAPTILER_KEY';
const map = new maptilersdk.Map({
container: 'map',
style: maptilersdk.MapStyle.STREETS,
center: [2.34, 48.86],
zoom: 13
});
map.on('load', () => {
map.addSource('route', {
type: 'geojson',
data: { type: 'Feature', geometry: { type: 'LineString',
coordinates: [[2.2945, 48.8584], [2.3376, 48.8606], [2.3500, 48.8530]]
}}
});
map.addLayer({
id: 'route-line', type: 'line', source: 'route',
paint: { 'line-color': '#9C27B0', 'line-width': 4 }
});
});Things to Know
Implementation-specific details that matter for lines & polylines.
L.polyline takes [lat, lng] arrays (reversed from GeoJSON); styling is set via options like color, weight, opacity, dashArray.
Line is a GeoJSON source + line layer; width, color, and dash-array are paint properties that support expressions.
Line is an ol.Feature with LineString geometry; stroke style supports width, color, and lineDash as style properties.
Same GeoJSON source + line layer approach as MapLibre; identical paint properties and expression support.
Which Library to Use?
Draw a styled L.polyline connecting multiple coordinates on a Leaflet map to visualize routes or paths.
The better fit for simple polylines where L.polyline with [lat, lng] coordinate arrays gets you a styled line in one call.
Draw a route or path on the map using a GeoJSON LineString source and a line layer with custom paint properties.
The right choice when lines need data-driven width, color, or dash patterns using style expressions on a GeoJSON line layer.
Add a styled line to an OpenLayers map using a vector source with ol.geom.LineString geometry.
Makes the most sense when line features need precise geographic measurements or must integrate with OGC vector data sources.
Draw a line on the map using a GeoJSON source and a line layer with custom paint properties.
Delivers MapLibre's line layer styling for MapTiler SDK users, with simplified setup.
Build Maps with AI
Generate code like these examples using mapping library skills in your IDE.