An open platform

When you hear the term web map, what comes to mind first? You might have thought of a road map – maps created to help you get from one place to another. However, there are many other types of maps that use the same mapping conventions.

Examples of custom web maps.

Mapbox is built from open specifications to serve all types of maps, not just road maps. Open specifications solve specific problems so the solution is simple and direct.

This guide runs through all the open specifications Mapbox uses.

Describing maps


TileJSON is a format that manages the complexities of custom maps. It organizes zoom levels, center points, legend contents, and more, into a format that makes it easy to display a map.

Here’s an example of what TileJSON looks like:

  "tiles": [ "{z}/{x}/{y}.png?access_token=<your access token here>" ],
  "minzoom": 0,
  "maxzoom": 18

To show a map, the TileJSON must have at least the tiles, minzoom, and maxzoom fields. All other fields are optional. By passing this snippet of JSON into Mapbox.js we can load and display the map mapbox.streets.

<!DOCTYPE html>
  <meta charset=utf-8 />
  <script src=''></script>
  <link href='' rel='stylesheet' />
    body { margin:0; padding:0; }
    .map { position:absolute; top:0; bottom:0; width:100%; }
<div id='map' class='map'> </div>
L.mapbox.accessToken = '<your access token here>';
var tilejson = {
  tiles: ['{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY5YzJzczA2ejIzM29hNGQ3emFsMXgifQ.az9JUrQP7klCgD3W-ueILQ'],
  minzoom: 0,
  maxzoom: 18
};'map', tilejson, {
  scrollWheelZoom: false
}).setView([43.6519, -79.3852], 15);
View source

Web maps can differ wildly and have a different answer for any number of questions:

  • What zoom level is supported?
  • What areas of the world does it cover?
  • Who should or must be credited for the map?

By making sensible assumptions, TileJSON simplifies the possible answers. TileJSON allows a map to define minzoom and maxzoom values to describe the zoom levels it supports. If a map claims minzoom:3 and maxzoom:8, TileJSON will assume that zoom levels 4,5,6,7 are also supported.

TileJSON in action

There are a couple ways that you can use TileJSON with Mapbox. All maps on Mapbox have an ID like mapbox.streets and a corresponding TileJSON endpoint:{mapid}.json?access_token=<your access token>

Read more about the endpoint API.

Mapbox.js JavaScript API. By calling'map', mapbox.streets) using Mapbox.js, the TileJSON for the map is downloaded and parsed.

By referencing a map’s TileJSON through an API URL, you can develop applications that manage multiple maps or switch between dozens of tile layers.

To learn more or to contribute to the TileJSON specification visit the project page on GitHub.

Styling features


Maintaining a distinction between content and visual styling can be tricky when annotating maps. The simplestyle spec is a practical approach to describing features on a map. It preserves data cleanly while allowing a light layer of visual style.

Other geodata formats define literal styles like this:

<img src="earthquake-6.png" />
<strong style="color:#f44">Virginia Earthquake 2011</strong>
<em>Magnitude 5.8</em>
No deaths, minor injuries. Damage to buildings reported.

That format requires extensive data parsing and makes it hard to maintain or change.

In contrast, simplestyle uses GeoJSON to define features. The same defining properties look like this:

    "title": "Virginia earthquake 2011 - mag. 5.8",
    "description": "No deaths, minor injuries. Damage to buildings reported.",
    "marker-symbol": "star",
    "marker-size": "medium",
    "marker-color": "#f44"

Nice, clean, and organized. On a map, the code looks like this:

simplestyle example

By providing basic fields for content, marker styles, and allowing additional data keys to be added for important values, simplestyle allows you to create uniform styles to be used across many features.

simplestyle in action

Any time you drop a pin or a draw line on a Mapbox map, you are creating GeoJSON that leverages the simplestyle spec. You can get that data by tapping into the markers API endpoint:{mapid}/{z}/{x}/{y}.{format}?access_token=<your access token>

The data from that path can be dropped directly into L.mapbox.markers.icon() in Mapbox.js to add markers to your map.

Be sure to check out the Extending with Mapbox.js guide where we go into styling marker and linestring data using simplestyle.

To learn more or to contribute to the simplestyle specification visit the project page on GitHub.

Storing tiles

Mapbox stores tiles with MBTiles and Vector tiles.


Tile based web maps are made up of millions of tiles. Imagine loading all of those tiles; it would be inefficient and slow. That’s where MBTiles comes in. The MBTiles specification is an efficient format for storing millions of tiles in a single SQLite database.

SQLite is ideal for serving tiles on the web or displaying directly on mobile devices because it’s used on so many platforms. If you’ve worked with SQL databases before, SQLite should feel very familiar. With SQLite, each database is self-contained and represented as a single .sqlite file. There’s no external setup required. You can copy a .sqlite file from desktop to a mobile device and have all its rows, tables, and indexes ready to be used. It’s a portable, single-file solution for storing and serving web maps.

MBTiles takes advantage of utilities found in SQLite for solving problems like duplicate imagery. Maps that cover large areas of solid color like ocean or empty land can contain thousands of duplicate, redundant tiles.

For example, a tile in the middle of the pacific ocean might look like this:

At higher zoom levels this could lead to millions of solid blue tiles, all exactly the same. Instead of loading all of those look-alike tiles, MBTiles can reference tile coordinates to raw imagery. Thousands of tile coordinates can be paired to the same raw image drastically reducing the filesize required to serve a map of multiple zoom levels.

MBTiles in action

TileMill uses MBTiles as the storage format used to export all the image tiles that make up your custom map. You can also use MBTiles files offline on mobile devices with Mapbox iOS toolkits. Vector tiles can also be stored in the MBTiles format; they’re not just for rasters!

To learn more or to contribute to the MBTiles specification visit the project page on GitHub.

Vector Tiles

Vector tiles are the vector data equivalent of image tiles for web mapping. They apply the strengths of tiling, developed for caching, scaling and serving map imagery rapidly, to vector data.

Consider an image tile at the zxy coordinate 14/4823/6160. This image is a PNG that depicts the corner of lower Manhattan with roads, building footprints, and parks:

A vector tile at 14/4823/6160 would contain all the corresponding geometries and metadata like road names, area types, building heights in a compact, parsable format.

Vector tiles are a highly performant format that provide greater flexibility in terms of styling, output format, and interactivity.

Vector tiles are designed to use the same tiling and coordinate scheme used by image tiles and take full advantage of HTTP. CDN caching, high scalability and efficient distribution make vector tiles a much more attractive solution than running, say, a enormous cluster of database and application servers that respond to queries on demand.

Vector Tiles in action

Mapbox Studio Classic is powered exclusively by vector tiles. Vector tile based style projects can be displayed on retina devices and be used for 600dpi printing in ways normal map image tiles cannot.

The vector tiles created by Mapbox Studio Classic can be used directly with Mapbox GL. As Mapbox GL rendering matures expect Mapbox Studio Classic to begin transitioning its rendering to leverage GL as well.

To learn more or to contribute to the Vector Tiles specification visit the project page on GitHub.

Scalable interactions


On a typical map you can have thousands of detailed features which all need to be interactive and usable on a variety of devices. The UTFGrid specification defines a way to transport interactive data to a map interface, like a tooltip, so that it loads progressively and performs well across legacy browsers and modern mobile devices.

Some of the most compelling stories that can be told with maps require thousands of interactive points or polygons.

Maps using UTFGrid for interactions.

As an example, here’s a map created in TileMill that plots the number of bird species in a squared off region. Hover over each square to see the UTFGrid data attributed to each one.

<!DOCTYPE html>
  <meta charset=utf-8 />
  <script src=''></script>
  <link href='' rel='stylesheet' />
    body { margin:0; padding:0; }
    .map { position:absolute; top:0; bottom:0; width:100%; }
<div id='map-with-utf' class='map dark'> </div>
L.mapbox.accessToken = '<your access token here>';'map-with-utf', '', {
  scrollWheelZoom: false,
  attributionControl: false,
  infoControl: true
}).setView([37, -80], 3);
View source

Map data as ASCII art

For older computers, drawing large amounts of vector data is slow or not supported at all. So what’s UTFGrid’s solution? Rasterize polygons and points as a grid of text characters.

Each feature is referenced by a distinct character and associated to JSON data by its character code. The result is a cheap, fast lookup that even Internet Explorer 7 can handle instantly.

UTFGrid tile data often looks like an ASCII art version of the corresponding map and is where the spec gets its name:

          !######$$$$%%% %%%% %
          !#######$$$$%%%    %%%
         !!#####   $$$%%%    %%%
         !######  $$$$%%% %% %%%
        !!!####  $$$$$%%%%  %%%%
      ! !###### $$$$$$%%%%%%%%%%
     ! !!#####  $$$$$$$%%%%%%%%%
    !!!!!####   $$$$$$%%%%%%%%%%
    !!!!!####   $$$$$$%%%%%%%%%%
    !!!!!####   $$$$$%%%%%%%%%%%
    !!!!!#####% $$   %%%%%%%%%%%
    !!!!!### #      %%%%%%%%%%%%
    !!! #####   ''''%%%%%%%%%%%%
     !   ###      ('%%%%%%%%%%%%
       ) ### #  ( ((%%%%%%%%%%%%
      ))  ##   (((((%%%%%%%%%%%%
      ))  #    ****(+%%%%%%%%%%%
       )        %**++++%%%%%%%%%
       , , ------*+++++%%%%%%%%%
.     ,,,,,------+++++++%%%%%%%%
..  /,,,,,,------++++++%%%%%%%%%
.  //,,,,,,------000++000%%%%%%%
22222::66666777788889900000 %%%%
22222:;;;;%%=7%8888890  0   %%%%
22222;;;; ==??%%888888  00 %%%%%
222222 ;;  =??%%%8888       %%%%
222     ;;   ?A>>@@@          B%
CCC      ;;   DEE@@@          BB

How it works

UTFGrid interaction is handled automatically by Mapbox.js and Mapbox iOS SDK. Under the hood, the process follows a simple tile retrieval and feature lookup workflow.

  1. When a user interaction occurs (hover, click or tap) a corresponding UTFGrid tile is downloaded.
  2. The x,y coordinates under the user interaction correspond to a character in the UTFGrid. In the grid above, a tap at column 13, row 4 would look up the # character.
  3. Each UTFGrid character corresponds to a distinct feature retrieved using a key mapping. In the grid above the characters are mapped such that
! => Norway
# => Sweden
$ => Finland

The feature JSON data is passed to a mustache template for display as HTML. Once rendered the data above is seen as an interactive map tooltip.

Population 9400000
Learn more on Wikipedia

UTFGrid in action

Any custom maps you make in TileMill with interaction make use of UTFGrid tiles in MBTiles exports. You can enable UTFGrid interaction on your maps using the L.mapbox.gridLayer() call in Mapbox.js.

To learn more or to contribute to the UTFGrid specification visit the project page on GitHub.

Next steps

Now that you’ve had the Mapbox open spec tour, we recommend that you dive into how web maps work.

Additional questions? Ask our support team or learn more about How Mapbox Works.