Skip to content
Leaflet.js API Reference & Cheatsheet

Leaflet.js API Reference & Cheatsheet

DodaTech Updated Jun 6, 2026 8 min read

Learning Path

    flowchart LR
    A["Leafletjs Overview"] --> B["Core Concepts"]
    B --> C["Intermediate Topics"]
    C --> D["Advanced Topics"]
    D --> E["Practical Applications"]
    A --> F["You Are Here"]
    style F fill:#f90,color:#fff
  

A complete Leaflet.js v1.9 reference for daily development. Use this as a quick cheatsheet while building your maps — bookmark it for easy access.

What You’ll Learn

This reference covers every major Leaflet API: map creation and options, tile layer configuration, markers and icons, popups and tooltips, vector layers (circles, polylines, polygons), GeoJSON, all built-in controls, event types, layer groups, overlays, and utility methods.

Why a Reference Matters

When you’re deep in code, you don’t want to read a tutorial — you need the exact syntax for L.circleMarker or the options object for L.icon. This page is that resource. Built by the developers of Doda Browser and Durga Antivirus Pro, it reflects the patterns we use daily in production mapping applications.

Security note: Understanding Leafletjs Reference helps build more secure applications — a core principle at DodaTech, where tools like Durga Antivirus Pro and Doda Browser rely on solid implementation practices.

Quick Start

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>#map { height: 400px; }</style>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
var map = L.map("map").setView([51.505, -0.09], 13);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
    attribution: "&copy; OpenStreetMap contributors"
}).addTo(map);
</script>

Map

L.map("id", {
    center: [lat, lng],       // Initial center
    zoom: 13,                  // Initial zoom
    minZoom: 1,
    maxZoom: 19,
    zoomControl: true,
    scrollWheelZoom: true,
    doubleClickZoom: true,
    touchZoom: true,
    dragging: true,
    keyboard: true,
    zoomSnap: 1,
    zoomDelta: 1,
    bounceAtZoomLimits: true,
    inertia: true,
    inertiaDeceleration: 3000,
    worldCopyJump: false,
    closePopupOnClick: true,
    trackResize: true,
    boxZoom: true,
    preferCanvas: false,
    renderer: L.svg() | L.canvas(),
    maxBounds: [[lat1,lng1],[lat2,lng2]],
    crs: L.CRS.EPSG3857
});

// View methods
map.setView([lat, lng], zoom, options)
map.setZoom(zoom, options)
map.fitBounds(bounds, options)
map.fitWorld(options)
map.panTo([lat, lng], options)
map.flyTo([lat, lng], zoom, options)
map.flyToBounds(bounds, options)
map.invalidateSize(options)       // Recalculate size after container resize
map.locate(options)                // Request browser geolocation

// Getting state
map.getCenter()               // LatLng
map.getZoom()                 // number
map.getBounds()               // LatLngBounds
map.getMinZoom()
map.getMaxZoom()
map.getSize()                 // Point [x, y]

// Layer management
map.addLayer(layer)
map.removeLayer(layer)
map.hasLayer(layer)
map.eachLayer(fn)
map.addControl(control)
map.removeControl(control)

Tile Layers

L.tileLayer(url, {
    minZoom: 1,
    maxZoom: 19,
    maxNativeZoom: 18,          // Provider's max zoom
    tileSize: 256,
    subdomains: ["a","b","c"],  // {s} in URL uses these
    errorTileUrl: "",            // Fallback on error
    zoomOffset: 0,
    tms: false,                  // TMS coordinate system
    detectRetina: false,
    crossOrigin: false,
    opacity: 1.0,
    zIndex: 1,
    attribution: ""
}).addTo(map);

// Common tile URLs
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png"
"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png"

Markers

L.marker([lat, lng], {
    icon: L.icon({ ... }),
    draggable: false,
    keyboard: true,
    title: "",                    // HTML title attribute
    alt: "",                      // Accessibility alt text
    zIndexOffset: 0,
    opacity: 1.0,
    riseOnHover: false,
    riseOffset: 250,
    pane: "markerPane",
    bubblingMouseEvents: false
}).addTo(map);

// Custom image icon
L.icon({
    iconUrl: "marker-icon.png",
    iconRetinaUrl: "marker-icon-2x.png",
    iconSize: [25, 41],
    iconAnchor: [12, 41],         // Tip of pin
    popupAnchor: [1, -34],
    shadowUrl: "marker-shadow.png",
    shadowSize: [41, 41],
    shadowAnchor: [12, 41]
});

// CSS/HTML icon
L.divIcon({
    className: "custom-div-icon",
    html: "<div>Content</div>",
    iconSize: [50, 50],
    iconAnchor: [25, 25],
    popupAnchor: [0, -25]
});

Popups & Tooltips

marker.bindPopup(content, options).openPopup()
marker.bindTooltip(content, options)

// Popup options
{
    maxWidth: 300,
    minWidth: 50,
    maxHeight: null,           // Scroll if set
    autoPan: true,
    autoPanPadding: [5, 5],
    keepInView: false,
    closeButton: true,
    closeOnClick: true,
    className: ""
}

// Tooltip options
{
    direction: "top",          // "right", "left", "top", "bottom", "center"
    permanent: false,
    sticky: false,             // Follow mouse
    interactive: false,
    opacity: 0.9,
    offset: L.point(0, 0)
}

Vector Layers

L.circle([lat, lng], { radius: 500, color: "red", fillColor: "#f03", fillOpacity: 0.5 })
L.circleMarker([lat, lng], { radius: 10, color: "red" })   // Pixel radius, fixed size
L.polyline([[lat,lng],[lat,lng]], { color: "blue", weight: 3 })
L.polygon([[lat,lng],[lat,lng],[lat,lng]], { color: "green" })
L.rectangle([[southWest],[northEast]], { color: "orange" })

// Common style options
{
    stroke: true,
    color: "#3388ff",
    weight: 3,
    opacity: 1.0,
    lineCap: "round",        // "butt", "round", "square"
    lineJoin: "round",       // "round", "bevel", "miter"
    dashArray: null,          // "10, 10"
    dashOffset: null,
    fill: true,
    fillColor: "#3388ff",
    fillOpacity: 0.2,
    fillRule: "evenodd",     // "nonzero", "evenodd"
    smoothFactor: 1.0,
    noClip: false,
    interactive: true,
    bubblingMouseEvents: false,
    renderer: L.svg() | L.canvas()
}

GeoJSON

L.geoJSON(data, {
    style: function(feature) { return {}; },
    filter: function(feature) { return true; },           // Skip features
    onEachFeature: function(feature, layer) {},            // Per-feature setup
    pointToLayer: function(feature, latlng) {             // Point rendering
        return L.circleMarker(latlng, { radius: 5 });
    },
    coordsToLatLng: function(coords) {
        return L.latLng(coords[1], coords[0]);  // [lng, lat] → [lat, lng]
    }
}).addTo(map);

Note: GeoJSON uses [longitude, latitude] order. Leaflet handles the conversion automatically.

Controls

// Layers control
L.control.layers(baseMaps, overlayMaps, {
    collapsed: false,
    position: "topright",
    autoZIndex: true,
    hideSingleBase: false
}).addTo(map);

// Zoom control
L.control.zoom({ position: "topleft", zoomInText: "+", zoomOutText: "-" })

// Scale control
L.control.scale({ position: "bottomleft", maxWidth: 200, metric: true, imperial: true })

// Attribution control
L.control.attribution({ position: "bottomright", prefix: "Leaflet" })

// Custom control
var ctrl = L.control({ position: "bottomleft" });
ctrl.onAdd = function(map) {
    var div = L.DomUtil.create("div", "info");
    div.innerHTML = "Content";
    L.DomEvent.disableClickPropagation(div);
    return div;
};
ctrl.addTo(map);

Events

// Map events
map.on("click", function(e) { e.latlng; e.layerPoint; e.containerPoint; })
map.on("dblclick", fn)
map.on("mousedown", fn) / map.on("mouseup", fn)
map.on("mouseover", fn) / map.on("mouseout", fn)
map.on("mousemove", fn)
map.on("contextmenu", fn)                    // Right-click
map.on("move", fn) / map.on("moveend", fn) / map.on("movestart", fn)
map.on("zoom", fn) / map.on("zoomend", fn) / map.on("zoomstart", fn)
map.on("resize", fn)
map.on("locationfound", fn) / map.on("locationerror", fn)
map.on("preclick", fn)                        // Fires before click

// Layer events
layer.on("click", fn) / layer.on("dblclick", fn)
layer.on("mouseover", fn) / layer.on("mouseout", fn)
layer.on("contextmenu", fn)
layer.on("dragstart", fn) / layer.on("drag", fn) / layer.on("dragend", fn)
layer.on("add", fn) / layer.on("remove", fn)
layer.on("popupopen", fn) / layer.on("popupclose", fn)
layer.on("tooltipopen", fn) / layer.on("tooltipclose", fn)

// Event management
.on("event", handler)              // Listen
.once("event", handler)            // Listen once, then auto-remove
.off("event", handler)             // Remove specific handler
.off("event")                      // Remove all handlers for event type
.off()                             // Remove all handlers
.fireEvent("event", data)          // Fire custom event
.hasEventListeners("event")        // Check for listeners

Layer Groups

L.layerGroup([layer1, layer2])                // Simple collection
L.featureGroup([layer1, layer2])              // With events + setStyle

group.addTo(map)
group.addLayer(layer)
group.removeLayer(layer)
group.clearLayers()
group.eachLayer(fn)
group.getBounds()
group.setStyle({ color: "red" })               // featureGroup only
group.bindPopup("Content")                     // All children get popup

Overlays

L.imageOverlay(url, bounds, { opacity: 0.8, interactive: false })
L.videoOverlay(url, bounds, { autoplay: true, loop: true, muted: true })
L.svgOverlay(bounds, { interactive: true })

Geocoding (Nominatim)

Convert an address to coordinates using OpenStreetMap’s free geocoding API:

fetch("https://nominatim.openstreetmap.org/search?q=London&format=json&limit=1")
    .then(function(r) { return r.json(); })
    .then(function(data) {
        if (data.length > 0) {
            map.setView([data[0].lat, data[0].lon], 12);
        }
    });

Utilities

L.latLng(lat, lng)                      // Create LatLng
L.latLngBounds(southWest, northEast)    // Create bounds
L.point(x, y)                           // Create pixel point
L.bounds(point1, point2)                // Pixel bounds

L.DomUtil.get("id")                     // Get element by ID
L.DomUtil.create("tag", "className", container)

L.DomEvent.on(el, "click", fn)          // DOM event
L.DomEvent.off(el, "click", fn)
L.DomEvent.stopPropagation(e)
L.DomEvent.preventDefault(e)
L.DomEvent.disableClickPropagation(el)
L.DomEvent.disableScrollPropagation(el)

Browser Detection

L.Browser.mobile        // Mobile device
L.Browser.touch         // Touch support
L.Browser.retina        // Retina display
L.Browser.webkit        // WebKit browser
L.Browser.gecko         // Firefox
L.Browser.ie            // IE/Edge

CDN Links

<!-- Leaflet Core -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

<!-- MarkerCluster -->
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css" />
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js"></script>

<!-- Leaflet Draw -->
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.js"></script>

<!-- Routing Machine -->
<link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.css" />
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script>

<!-- Heatmap -->
<script src="https://unpkg.com/leaflet.heat@0.2.0/dist/leaflet-heat.js"></script>

<!-- Fullscreen -->
<link rel="stylesheet" href="https://unpkg.com/leaflet.fullscreen@2.4.0/dist/leaflet.fullscreen.css" />
<script src="https://unpkg.com/leaflet.fullscreen@2.4.0/dist/Leaflet.fullscreen.js"></script>

Common Plugin List

PluginPurpose
leaflet.markerclusterMarker clustering for large datasets
leaflet.heatHeatmap layer
leaflet-routing-machineTurn-by-turn directions
leaflet-drawDrawing tools
leaflet.fullscreenFullscreen toggle
leaflet-searchSearch/autocomplete
Leaflet.EasyButtonSimple button control
leaflet-providersTile provider presets
leaflet-gpxGPX track display
leaflet-velocityWind animation
leaflet-ant-pathAnimated polylines
leaflet.patternPattern fills for polygons

Common Mistakes

1. Map container missing explicit height

The map’s container <div> must have a CSS height or the map renders at 0px tall.

2. Wrong coordinate order

Leaflet uses [lat, lng]. GeoJSON uses [lng, lat]. Confusing them is the #1 mapping bug.

3. Tile layer not added to map

L.tileLayer() returns a layer — nothing shows until .addTo(map) is called.

4. Plugin CSS not loaded

Many plugins need CSS files. Missing CSS causes broken controls. Check browser console for 404s.

5. Not cleaning up map instances in SPAs

Call map.remove() in component cleanup to prevent memory leaks in React, Vue, or Angular.

FAQ

What Leaflet version should I use?
Use v1.9.4 (latest stable). Most plugins are compatible with the 1.x line.
Why are my markers invisible?
Check that: 1) the marker’s coordinates are within the current map view, 2) the map has a CSS height, and 3) you called .addTo(map).
How do I change the default marker color?
Use L.icon() with a custom image URL, or use L.divIcon() with inline CSS/SVG.
What is the difference between L.circle and L.circleMarker?
L.circle radius is in meters (scales with zoom). L.circleMarker radius is in pixels (fixed size).
Can Leaflet work offline?
Yes, if you cache tile images. Leaflet itself has no online dependencies.

Try It Yourself

Use this minimal template to test any Leaflet feature quickly:

<!DOCTYPE html>
<html>
<head>
    <title>Leaflet Test</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
    <style>body { margin: 0; } #map { height: 100vh; }</style>
</head>
<body>
    <div id="map"></div>
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
    <script>
        var map = L.map("map").setView([51.505, -0.09], 13);
        L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
            attribution: "&copy; OpenStreetMap"
        }).addTo(map);

        // Add your test code here
    </script>
</body>
</html>

What’s Next

LessonDescription
Leaflet.js Basics →Start from the beginning
Advanced & Plugins →Heatmaps, routing, performance

Related Topics: JavaScript | SVG for custom markers | JSON for GeoJSON data

What’s Next

Congratulations on completing this Leafletjs Reference tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro