Skip to content


Subversion checkout URL

You can clone with
Download ZIP
A lightweight set of tools for working with ArcGIS services with Leaflet.
JavaScript HTML CSS Shell

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.

Esri Leaflet

Leaflet plugin for Esri ArcGIS Online Services. Currently only supports loading Esri basemaps and feature services, as well as map services.

The goal of Esri Leaflet is not to replace the ArcGIS API for JavaScript, but rather to provide small components to allow developers to build simple lightweight mapping applications. It pairs well with Terraformer for converting data and geoservices-js for making advanced request to ArcGIS REST services, for example place finding and reverse geocoding.

Currently Esri Leaflet is in development but is open to contributions. It should be thought of as a beta or preview.


There are loads of demos showing the features of Esri Leaflet as well as how it might integrate with geoservices-js and Terraformer libraries. Check out the demos.

Quick Example

Here is a quick example to get you started. Just change the paths to point to the proper libraries and go.


<!DOCTYPE html>
    <title>Esri Leaflet</title>
    <link rel="stylesheet" href="/the/path/to/leaflet.css" />
      html, body,  #map {
        width : 100%;
        height : 100%;
    <script src="/the/path/to.leaflet.js"></script>
    <script src="/the/path/to/esri-leaflet.min.js"></script>
    <!--[if lte IE 8]><link rel="stylesheet" href="/the/path/to/" /><![endif]-->
    <script src="/the/path/to.leaflet.js"></script>
    <script src="/the/path/to/esri-leaflet.js"></script>
    <div id="map"></div>
      var map ='map');

      // ArcGIS Online Basemaps - Streets, Topographic, Gray, GrayLabels, Oceans, NationalGeographic, Imagery, ImageryLabels

      function onLocationFound(e) {
        var radius = e.accuracy / 2;
        L.marker(e.latlng).addTo(map).bindPopup("You are within " + radius + " meters from this point").openPopup();, radius).addTo(map);

      function onLocationError(e) {

      map.on('locationfound', onLocationFound);
      map.on('locationerror', onLocationError);

      map.locate({setView: true, maxZoom: 16});



You can quickly access ArcGIS base maps with the L.esri.BasemapLayer(key, options) layer. The key parameter should be one of the following keys.

  • Streets
  • Topographic
  • Oceans
  • NationalGeographic
  • Gray
  • GrayLabels
  • Imagery
  • ImageryLabels

The options parameter can accept the same options as L.TileLayer.

var map ='map').setView([37.75,-122.45], 12);


Esri Leaflet has support for FeatureLayers via L.esri.FeatureLayer(url, options). The url parameter is the url to the FeatureLayer you should like to display.

var map ='map').setView([45.52963623111275,-122.67389774322508], 12);

The options parameter can accept anything that L.GeoJSON can accept. This means you can apply popups, custom styles and filters. See Leaflet GeoJSON for more information.


If you have a MapService you and use L.esri.DynamicMapLayer(url, options) to render it over a map. It takes a url to a MapService and options.

var map ='map').setView([ 38.24788726821097,-85.71807861328125], 13 );

L.esri.dynamicMapLayer("", {
  opacity : 0.25


It is possible to show/hide specific layers and set layer definitions within options like so...

L.esri.dynamicMapLayer("", {
  opacity : 0.5,
  layerDefs: {
    5: "STATE_NAME='Kansas'",
    4: "STATE_NAME='Kansas' and POP2007>25000",
    3: "STATE_NAME='Kansas' and POP2007>25000"

You can identify features from MapService using L.esri.DynamicMapLayer.identify(latLng, options, callback).

dynLayer.identify(e.latlng, {
  sr: '4265', //default is '4326'
  tolerance: 5, //default is 3
  imageDisplay: '801,601,97', // default is '800,600,96' (height by width in pixels and DPI)
} , callback)

Take a look at this sample for a demonstration.


Esri Leaflet can work with tiled map services as well. You can use L.esri.TiledMapLayer(url, options) to use tiled map services. The url parameter is the url to the MapServer and options is identical to the options you can pass to L.TileLayer.

var map ='map').setView([ 37.761487048570935, -122.39112854003905], 12 );

L.esri.basemapLayer("Gray", {

L.esri.tiledMapLayer("", {
  opacity: 0.25,

L.esri.basemapLayer("GrayLabels", {


L.esri.ClusteredFeatureLayer provides integration for Feature Layers with the Leaflet.markercluster plugin. Because of the extra Dependency on Leaflet.markercluster we do not include L.esri.ClusteredFeatureLayer in the default build of Esri Leaflet. It lives in /dist/extras/clustered-feature-layer.js. You will also need to include your own copy of the Leaflet.markercluster plugin.

L.esri.clusteredFeatureLayer(featureLayerUrl, {

  // this should be an instance of L.MarkerClusterGroup
  cluster: new L.MarkerClusterGroup(),

  // this function should return a new L.Marker
  // that will be added to the cluster.
  createMarker: function(geojson, latlng){},

  // this optional function will be run against 
  // every marker before it is added to the cluster
  // this is a great place to define custom popups
  // or other behaviors.
  onEachMarker: function(geojson, marker){



L.esri.clusteredFeatureLayer("", {
  cluster: new L.MarkerClusterGroup({
    disableClusteringAtZoom: 16,
    polygonOptions: {
      color: "#2d84c8",
      weight: 4,
      opacity: 1,
      fillOpacity: 0.5
    iconCreateFunction: function(cluster) {
      var count = cluster.getChildCount();
      var digits = (count+"").length;
      return new L.DivIcon({
        html: count,
        className:"cluster digits-"+digits,
        iconSize: null
  marker: function (geojson, latlng) {
    return L.marker(latlng, {
      icon: icons[]
  eachMarker: function(geojson, marker) {
    marker.bindPopup("<h3>""</h3><p>Stop ID: ""</p><p>""</p>")

Development Instructions

  1. git clone
  2. cd esri-leaflet
  3. git submodule init
  4. git submodule update


  • All services that Esri Leaflet accesses must be publicly available. Support for private services will be included in a future release.
  • MapServices that you wish to use for L.esri.TiledMapLayer must be published in Web Mercator.


These are currently included in /vendor as submodules and are built into the dist/esri-leaflet.js file.

Custom Builds

It is possible to build a custom version of Esri Leaflet by customizing the Gruntfile. To do this add a new entry to the concat and the uglify configurations. More detailed directions will be added here later.



Find a bug or want to request a new feature? Please let us know by submitting an issue.


Esri welcomes contributions from anyone and everyone. Please see our guidelines for contributing.


Dymanic Map Layer code is based on code from


Copyright 2013 Esri

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

A copy of the license is available in the repository's license.txt file.

Something went wrong with that request. Please try again.