diff --git a/packages/geojson-extension/package.json b/packages/geojson-extension/package.json
index 047f182e5..46d213e86 100644
--- a/packages/geojson-extension/package.json
+++ b/packages/geojson-extension/package.json
@@ -24,10 +24,12 @@
     "@jupyterlab/rendermime-interfaces": "^1.0.3",
     "@phosphor/messaging": "^1.2.2",
     "@phosphor/widgets": "^1.5.0",
-    "leaflet": "^1.2.0"
+    "@turf/bbox": "^6.0.1",
+    "leaflet": "^1.2.0",
+    "mapbox-gl": "^0.44.2"
   },
   "devDependencies": {
-    "@types/leaflet": "^1.2.0",
+    "@types/mapbox-gl": "^0.44.1",
     "rimraf": "~2.6.2",
     "typescript": "~2.6.2"
   },
diff --git a/packages/geojson-extension/src/index.tsx b/packages/geojson-extension/src/index.tsx
index 918c318ad..424344f41 100644
--- a/packages/geojson-extension/src/index.tsx
+++ b/packages/geojson-extension/src/index.tsx
@@ -13,15 +13,14 @@ import {
   IRenderMime
 } from '@jupyterlab/rendermime-interfaces';
 
-import * as leaflet from 'leaflet';
+import mapboxgl = require('mapbox-gl');
+
+import bbox from '@turf/bbox';
 
 import 'leaflet/dist/leaflet.css';
 
 import '../style/index.css';
 
-import * as iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
-import * as iconUrl from 'leaflet/dist/images/marker-icon.png';
-import * as shadowUrl from 'leaflet/dist/images/marker-shadow.png';
 
 /**
  * The CSS class to add to the GeoJSON Widget.
@@ -39,39 +38,7 @@ const CSS_ICON_CLASS = 'jp-MaterialIcon jp-GeoJSONIcon';
 export
 const MIME_TYPE = 'application/geo+json';
 
-/**
- * Set base path for leaflet images.
- */
-
-// https://github.com/Leaflet/Leaflet/issues/4968
-// Marker file names are hard-coded in the leaflet source causing
-// issues with webpack.
-// This workaround allows webpack to inline all marker URLs.
-
-delete (leaflet.Icon.Default.prototype as any)['_getIconUrl'];
-
-leaflet.Icon.Default.mergeOptions({
-  iconRetinaUrl: iconRetinaUrl,
-  iconUrl: iconUrl,
-  shadowUrl: shadowUrl
-});
-
-
-/**
- * The url template that leaflet tile layers.
- * See http://leafletjs.com/reference-1.0.3.html#tilelayer
- */
-const URL_TEMPLATE: string = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
-
-/**
- * The options for leaflet tile layers.
- * See http://leafletjs.com/reference-1.0.3.html#tilelayer
- */
-const LAYER_OPTIONS: leaflet.TileLayerOptions = {
-  attribution: 'Map data (c) <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',
-  minZoom: 0,
-  maxZoom: 18
-};
+mapboxgl.accessToken = 'pk.eyJ1IjoibWlja3QiLCJhIjoiLXJIRS1NbyJ9.EfVT76g4A5dyuApW_zuIFQ';
 
 
 export
@@ -82,14 +49,7 @@ class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
   constructor(options: IRenderMime.IRendererOptions) {
     super();
     this.addClass(CSS_CLASS);
-    this._mimeType = options.mimeType;
-    // Create leaflet map object
-    // trackResize option set to false as it is not needed to track
-    // window.resize events since we have individual phosphor resize
-    // events.
-    this._map = leaflet.map(this.node, {
-        trackResize: false
-    });
+    this._mimeType = options.mimeType;    
   }
 
   /**
@@ -107,17 +67,35 @@ class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
    */
   renderModel(model: IRenderMime.IMimeModel): Promise<void> {
     const data = model.data[this._mimeType] as any | GeoJSON.GeoJsonObject;
-    const metadata = model.metadata[this._mimeType] as any || {};
+    // const metadata = model.metadata[this._mimeType] as any || {};
+    this._map = new mapboxgl.Map({
+      container: this.node,
+      style: 'mapbox://styles/mapbox/streets-v9?optimize=true',
+      zoom: 10
+    });
     return new Promise<void>((resolve, reject) => {
-      // Add leaflet tile layer to map
-      leaflet.tileLayer(
-        metadata.url_template || URL_TEMPLATE,
-        metadata.layer_options || LAYER_OPTIONS
-      ).addTo(this._map);
-      // Create GeoJSON layer from data and add to map
-      this._geoJSONLayer = leaflet.geoJSON(data).addTo(this._map);
-      this.update();
-      resolve();
+      // Add GeoJSON layer to map
+      this._map.on('style.load', () => {
+        this._map.addSource('geojson', {
+          type: 'geojson',
+          data
+        });
+        const [minX, minY, maxX, maxY] = bbox(data);
+        this._map.fitBounds([[minX, minY], [maxX, maxY]], { maxZoom: 15, padding: 100 });
+        this._map.addLayer({
+          id: 'geojson-points',
+          type: 'circle',
+          source: 'geojson',
+          paint: {
+            'circle-color': 'red',
+            'circle-stroke-color': 'white',
+            'circle-stroke-width': { stops: [[0,0.1], [18,3]], base: 1.2 },
+            'circle-radius': { stops: [[15,3], [18,5]], base: 1.2 }
+          }
+        });
+        this.update();
+        resolve();
+      });
     });
   }
   
@@ -125,19 +103,20 @@ class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
    * A message handler invoked on an `'after-attach'` message.
    */
   protected onAfterAttach(msg: Message): void {
-    if (this.parent.hasClass('jp-OutputArea-child')) {
-      // Disable scroll zoom by default to avoid conflicts with notebook scroll
-      this._map.scrollWheelZoom.disable();
-      // Enable scroll zoom on map focus
-      this._map.on('blur', (event) => {
-        this._map.scrollWheelZoom.disable();
-      });
-      // Disable scroll zoom on blur
-      this._map.on('focus', (event) => {
-        this._map.scrollWheelZoom.enable();
-      });
-    }
-    this.update();
+    // If in a notebook context
+    // if (this.parent.hasClass('jp-OutputArea-child')) {
+    //   // Disable scroll zoom by default to avoid conflicts with notebook scroll
+    //   this._map.scrollZoom.disable();
+    //   // Enable scroll zoom on map focus
+    //   this._map.on('blur', (event: Event) => {
+    //     this._map.scrollZoom.disable();
+    //   });
+    //   // Disable scroll zoom on blur
+    //   this._map.on('focus', (event: Event) => {
+    //     this._map.scrollZoom.enable();
+    //   });
+    // }
+    // this.update();
   }
   
   /**
@@ -159,13 +138,13 @@ class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
    */
   protected onUpdateRequest(msg: Message): void {
     // Update map size after update
-    if (this.isVisible) this._map.invalidateSize();
-    // Update map size after panel/window is resized
-    this._map.fitBounds(this._geoJSONLayer.getBounds());
+    if (this._map && this.isVisible) {
+      this._map.resize();
+    }
   }
 
-  private _map: leaflet.Map;
-  private _geoJSONLayer: leaflet.GeoJSON;
+  private _map: mapboxgl.Map;
+  // private _geoJSONLayer: mapboxgl.GeoJSONSource;
   private _mimeType: string;
 }
 
diff --git a/yarn.lock b/yarn.lock
index 9d29cb421..d1a559a8b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -311,6 +311,23 @@
     d3-collection "1"
     d3-interpolate "1"
 
+"@turf/bbox@^6.0.1":
+  version "6.0.1"
+  resolved "https://registry.npmjs.org/@turf/bbox/-/bbox-6.0.1.tgz#b966075771475940ee1c16be2a12cf389e6e923a"
+  dependencies:
+    "@turf/helpers" "6.x"
+    "@turf/meta" "6.x"
+
+"@turf/helpers@6.x":
+  version "6.1.3"
+  resolved "https://registry.npmjs.org/@turf/helpers/-/helpers-6.1.3.tgz#0001a5c4a3bff25b4bbbc64f8713a383c9ab9e94"
+
+"@turf/meta@6.x":
+  version "6.0.1"
+  resolved "https://registry.npmjs.org/@turf/meta/-/meta-6.0.1.tgz#cf6f3f2263a3d24fc8d6a7e90f0420bbc44c090d"
+  dependencies:
+    "@turf/helpers" "6.x"
+
 "@types/d3-array@*":
   version "1.2.1"
   resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.1.tgz#e489605208d46a1c9d980d2e5772fa9c75d9ec65"
@@ -503,9 +520,9 @@
   version "0.5.0"
   resolved "https://registry.npmjs.org/@types/katex/-/katex-0.5.0.tgz#a7dbb981f1bc89c8b1b5e7fa8a1ce2617ab2f358"
 
-"@types/leaflet@^1.2.0":
-  version "1.2.5"
-  resolved "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.2.5.tgz#b172502c298849cadd034314dabfc936beff7636"
+"@types/mapbox-gl@^0.44.1":
+  version "0.44.1"
+  resolved "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-0.44.1.tgz#6d8618ab2a28e8b78ce2cca403f28a227c9f217d"
   dependencies:
     "@types/geojson" "*"
 
@@ -3439,6 +3456,42 @@ mapbox-gl@^0.44.0:
     vt-pbf "^3.0.1"
     webworkify "^1.5.0"
 
+mapbox-gl@^0.44.2:
+  version "0.44.2"
+  resolved "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-0.44.2.tgz#8c118ba8c5c15b054272644f30877309db0f8ee2"
+  dependencies:
+    "@mapbox/gl-matrix" "^0.0.1"
+    "@mapbox/mapbox-gl-supported" "^1.3.0"
+    "@mapbox/point-geometry" "^0.1.0"
+    "@mapbox/shelf-pack" "^3.1.0"
+    "@mapbox/tiny-sdf" "^1.1.0"
+    "@mapbox/unitbezier" "^0.0.0"
+    "@mapbox/vector-tile" "^1.3.0"
+    "@mapbox/whoots-js" "^3.0.0"
+    brfs "^1.4.0"
+    bubleify "^0.7.0"
+    csscolorparser "~1.0.2"
+    earcut "^2.1.3"
+    geojson-rewind "^0.3.0"
+    geojson-vt "^3.0.0"
+    gray-matter "^3.0.8"
+    grid-index "^1.0.0"
+    jsonlint-lines-primitives "~1.6.0"
+    minimist "0.0.8"
+    package-json-versionify "^1.0.2"
+    pbf "^3.0.5"
+    quickselect "^1.0.0"
+    rw "^1.3.3"
+    shuffle-seed "^1.1.6"
+    sort-object "^0.3.2"
+    supercluster "^2.3.0"
+    through2 "^2.0.3"
+    tinyqueue "^1.1.0"
+    unassertify "^2.0.0"
+    unflowify "^1.0.0"
+    vt-pbf "^3.0.1"
+    webworkify "^1.5.0"
+
 marching-simplex-table@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npmjs.org/marching-simplex-table/-/marching-simplex-table-1.0.0.tgz#bc16256e0f8f9b558aa9b2872f8832d9433f52ea"