# geojson-vt: slicing GeoJSON into vector tiles in the browser, with ten options to tune output

> geojson-vt is a JavaScript library that converts a GeoJSON object into a tile index and serves individual vector tiles by zoom level and tile coordinates, entirely in the browser or in Node.js without a server. getTileRaw returns typed arrays that belong to the index and must not be held past its lifetime.

**mapbox/geojson-vt** — Slice GeoJSON into vector tiles on the fly in the browser

- Repository: https://github.com/mapbox/geojson-vt
- Stars: 2,078 · Forks: 280
- Language: JavaScript
- License: ISC
- Published: 2026-10-11 · Updated: 2026-10-11 · Language: en
- Canonical page: https://hysenlabs.com/projects/mapbox-geojson-vt

## Client-side tile generation: the browser holds the full GeoJSON and slices as needed

Most vector tile workflows assume a preprocessing step: data is sliced on a server, stored as a tile archive and served over HTTP. geojson-vt removes that server step by running the slicing in JavaScript. Created by Vladimir Agafonkin to power GeoJSON support in Mapbox GL JS, it also supports Leaflet, OpenLayers, d3 and server-side Node.js applications.

Output tiles follow the JSON encoding of the Mapbox vector tile specification, so any renderer that understands that format can consume them directly. Simplification is applied during tiling: at lower zoom levels, shapes are generalized and small features are dropped, while higher zoom levels retain more detail. A tile at zoom 2 and a tile at zoom 14 therefore carry different subsets of the same input geometry.

A demonstration in the README loads a 100MB US zip code GeoJSON with 5.4 million points into Mapbox GL JS. A debug page at mapbox.github.io/geojson-vt/debug/ accepts any GeoJSON dropped onto it and shows what tiles are produced, which is useful for inspecting simplification results before integration.

## indexMaxZoom splits work: pre-built tiles up to zoom 5, on-demand slicing above that

Constructing a GeoJSONVT object triggers an indexing pass. Tiles for zoom levels 0 through 5 are pre-built and held in memory by default; requests for higher zoom levels are computed on demand when getTile or getTileRaw is called for a specific coordinate. Two options control that split.

indexMaxZoom sets the ceiling for pre-built tiles (default 5). indexMaxPoints limits how many points a pre-built tile can hold before the library subdivides it further (default 100000). Lowering indexMaxPoints produces more, smaller tiles at index time. Raising it consolidates geometry into fewer tiles, which may reduce memory use but increases per-tile complexity.

To pre-generate all tiles up to a given zoom level, the README describes setting indexMaxZoom and maxZoom to the same value and setting indexMaxPoints to 0. After indexing, reading tileIndex.tileCoords gives an array of {z, x, y} objects for every tile created, which is useful for verifying coverage. Tiles above maxZoom are never generated regardless of request.

## Installing with npm and making the first tile request

Install from npm with:

```bash
npm install geojson-vt
```

Import the default export in a module context:

```js
import GeoJSONVT from 'geojson-vt';
```

For a browser CDN import without npm:

```js
import GeoJSONVT from 'https://esm.run/geojson-vt';
```

Once imported, construct an index and request a tile:

```js
const tileIndex = new GeoJSONVT(geoJSON);
const features = tileIndex.getTile(z, x, y).features;
console.log(tileIndex.tileCoords);
```

getTile returns null when a requested coordinate falls entirely outside the area covered by the input data, so code must check for null before accessing .features. Tile coordinates already created are listed in tileIndex.tileCoords as {z, x, y} objects. A browser bundle is also available directly at https://unpkg.com/geojson-vt/geojson-vt.js, which exposes GeoJSONVT as a global for script tag use.

## getTile allocates on every call; getTileRaw hands back the index's internal typed arrays

Two methods retrieve tile data. getTile builds a fresh structure on each call, returning features with coordinates as [x, y]-pair objects. This is straightforward to iterate but allocates heap memory for every request. In a rendering loop that requests many tiles per second, that allocation adds up.

getTileRaw returns the tile as stored internally: flat typed arrays in [x, y, x, y, ...] form, one array per ring, skipping the per-coordinate object creation entirely. This zero-copy path is faster but carries a strict ownership rule. Direct quotes from the README state that these arrays belong to the index and must be treated as read-only, and callers must not hold references to them past the tile index's lifetime. Keeping a reference to a typed array from getTileRaw after the GeoJSONVT object is replaced or collected will produce stale data.

Feature geometry encoding also differs between the two methods. getTileRaw uses an internal type system: type 4 is a lone point with inline x and y, type 1 is a multi-point stored as a single flat array, and types 2 and 3 represent lines and polygons as arrays of rings. Code consuming getTileRaw output must handle those four cases rather than standard GeoJSON geometry types.

## Ten options govern simplification, ID assignment and index capacity

Passing an options object to the GeoJSONVT constructor gives access to ten configuration keys. Defaults are provided for all of them.

maxZoom controls the highest zoom level at which detail is preserved (default 14, ceiling 24). tolerance adjusts simplification aggressiveness: higher values produce simpler output. extent sets the coordinate space size of each tile, defaulting to 4096 to match the convention used by common renderers. buffer adds a margin around each tile edge to prevent geometry clipping.

debug accepts 0, 1 or 2 to control log verbosity, while lineMetrics enables tracking for LineString and MultiLineString features and is false by default.

The two ID options require care. promoteId names a feature property to use as the feature's id. generateId assigns sequential ids automatically. According to the README, both options ignore any id values already present on incoming feature objects. A pipeline where features carry meaningful ids from upstream must avoid both options, or those ids will be silently overwritten. promoteId and generateId cannot be used together.

## Hard ceiling at zoom 24 and three other constraints

Requesting a tile at zoom 25 or higher falls outside what the library supports. Zoom 24 is the absolute maximum, documented both in the README and in the maxZoom option description. Any visualization that needs finer subdivision must generate those extra-fine tiles through another method.

A second constraint is memory. Indexing requires the entire GeoJSON to reside in a single process. For a 100MB dataset that is feasible in a browser, as the README demonstrates, but there is no streaming or incremental indexing path. Datasets too large for a tab's memory allocation cannot be indexed at all.

Projection is a third constraint. geojson-vt operates on geographic coordinates and does not reproject input. Data in other coordinate systems needs conversion before indexing. The library does not document behavior for non-geographic input, so reprojected or custom-CRS data should be treated as unsupported.

A fourth note: getTile and getTileRaw do not document their behavior outside the data boundary for all edge cases. getTile returns null outside the data, but the README does not say what getTileRaw returns for the same coordinates. Code that uses getTileRaw should guard against null or undefined as a safety measure.

## Server-generated tiles and the C++11 port as contrasting approaches

Generating tiles on a server before a browser requests them is the other main approach. A server pipeline processes the GeoJSON once, stores output as a tile archive or live tile service, and serves small tiles over HTTP without any client-side indexing cost. Datasets of any size can be handled, and memory per request is bounded. A change to the underlying data requires re-running the build step, and deployments need tile storage or a tile server.

geojson-vt trades that infrastructure for immediacy: data can be dropped into a browser session and rendered without a preprocessing step. For data that changes frequently, comes from user uploads or is generated interactively, the server pipeline would need to re-run on every change. That is the tradeoff the library is designed to fill.

For environments outside JavaScript, a C++11 port named geojson-vt-cpp is maintained at github.com/mapbox/geojson-vt-cpp. The README links to it without specifying feature parity or version correspondence, so checking that repository directly is necessary before depending on it in a C++ project.

## Conclusion

Use geojson-vt when rendering or querying large GeoJSON client-side and a server tile pipeline is not available or not worth the setup. Skip it when your dataset grows beyond what a browser tab can hold in memory, when zoom levels above 24 are required, or when features need to arrive at the renderer without simplification at lower zoom levels. Before shipping, check what your simplification tolerance produces at each target zoom level using the debug page at mapbox.github.io/geojson-vt/debug/, and confirm whether promoteId or generateId will overwrite id values your pipeline depends on.

## FAQ

### What is geojson-vt?

geojson-vt is a JavaScript library that slices a GeoJSON object into vector tiles in the browser or Node.js without a server. It was created to power GeoJSON support in Mapbox GL JS and also works with Leaflet, OpenLayers and d3.

### How do I install geojson-vt?

Install it from npm with npm install geojson-vt and import the default export as import GeoJSONVT from 'geojson-vt'. A CDN import is also available at https://esm.run/geojson-vt for browser use without npm.

### What is the difference between getTile and getTileRaw in geojson-vt?

getTile allocates a fresh coordinate structure on every call while getTileRaw returns direct references into the index's typed arrays, avoiding allocation. The getTileRaw arrays belong to the index and must be treated as read-only and not held past the index's lifetime.

### Can geojson-vt be used with TypeScript?

Type declarations ship with the library, so no separate @types/geojson-vt package is needed. The README advises removing that package if it is already installed.

### What is the maximum zoom level supported by geojson-vt?

Zoom 24 is the ceiling. The maxZoom option cannot be set higher than 24, so any visualization requiring resolution beyond that level must use another tiling method for those zoom levels.

## Sources

- [Issues](https://github.com/mapbox/geojson-vt/issues)
- [License: ISC](https://github.com/mapbox/geojson-vt/blob/main/LICENSE)
- [mapbox/geojson-vt on GitHub](https://github.com/mapbox/geojson-vt)
- [README](https://github.com/mapbox/geojson-vt/blob/main/README.md)
- [Releases](https://github.com/mapbox/geojson-vt/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mapbox-geojson-vt
