Web map engines, feature by feature: MapLibre, Cesium, TerriaJS, Navara and ortho-earth

2026-10-21 · Kenji Yoshida

Introduction

In the previous story I drew the PLATEAU buildings with five engines and compared their speed. This one is its companion: it compares what they can do. I checked each point against the documentation and source of the versions used in the benchmark: MapLibre GL JS 6.15.0 (with deck.gl 9.4), CesiumJS 1.146, TerriaJS 8.13.0 (its Cesium is about 1.142), Navara (@navaramap/three 0.2.1) and ortho-earth (@ortho-earth/globe 2.0.2).

Again, a disclosure first: I am the developer of ortho-earth. I have tried to say where the other engines are strong, and where ortho-earth falls short.

In short: different starting points

All five are called map engines, but they start from different places. MapLibre grew out of 2D cartography (vector tiles and labels), Cesium out of a 3D Earth with time. Terria is a finished data-viewing app built on Cesium, Navara pairs a Rust GIS core with photorealistic three.js rendering, and ortho-earth puts the MapLibre API on an always-round globe.

So they do not line up on a single scale of more or fewer features. For expressive 2D maps, MapLibre is strongest; for depth in 3D Tiles and time-varying data, Cesium; for a complete kit to gather and present data, Terria; for photorealistic rendering, Navara. What ortho-earth has that no other does is the combination: MapLibre's way of writing a map and Cesium's 3D and clock on one sphere, with rendering moved to a worker.

MapLibre (+deck.gl)CesiumTerriaNavaraortho-earth
What it is2D map library3D Earth libraryFinished data viewer (Cesium + Leaflet)3D map library (Rust/WASM + three.js)3D globe library
ProjectionMercator at heart; globe only at low zoom, turning into Mercator as you zoom inWGS84 ellipsoid; morphs to 2D and Columbus view3D is Cesium, 2D is Leaflet (Web Mercator)Sphere (ellipsoid) onlySphere only (ellipsoid optional); flat maps in Equal Earth
GPUWebGL2 (deck.gl is trying WebGPU)WebGL2WebGL2WebGL2 (three.js)WebGPU, else WebGL2
Render threadMain (tile decoding in workers)Main (decoding and geometry in workers)Main (with the React UI)Main (heavy work in workers)Render worker (OffscreenCanvas)
3D TilesNot in core; overlaid with deck.glNearly all of 1.0/1.1, I3S, point clouds, splats, voxelsSame as Cesium (I3S too)b3dm, pnts, glb (no i3dm or cmpt yet), splatsb3dm, i3dm, pnts, cmpt, glb, I3S, COPC, splats (plugin)
Terrainraster-dem (hillshade, colour relief)quantized-mesh, Google, ionSame as Cesiumraster-dem, quantized-meshraster-dem, quantized-mesh
Vector tilesMVT, MLT; home of the style specMVT converted to 3D Tiles (1.142+)MVT baked into images (protomaps)MVT, PMTiles, partial MapLibre styleMVT, MLT, PMTiles, MapLibre style
LabelsSDF text, collision, along lines, verticalLabelCollection; no collision, grouping via EntityClusterSame as CesiumSDF text, along lines, web fonts (no glyph PBF)Drawn with Canvas2D; collision, along lines, icons, vertical, 26 languages
TimeNo clock (deck.gl Trips has currentTime)Clock, Timeline, interpolated CZMLTime slider (WMS time, CSV, CZML)Sun date, glTF animationmap.clock (CZML, satellites, stars, night side, trips)
PickingqueryRenderedFeatures, feature-statepick, drillPick, pickPosition, tile propertiesFeature info panel (templates)GPU click and hover, terrain/depth positionqueryRenderedFeatures, GPU ids, overlays too
AnalysisNone (add Turf etc.)Clipping, shadows, sampleTerrainSplit-screen compare, measuring, storiesShadows, geodesic measuring, terrain heightShadow and sun hours, viewshed, line of sight, profiles, measuring
LookSky, fog, light (within 2D)Atmosphere, shadows, PBR, point-cloud EDLSame as Cesium (30 fps cap and shadows by default)Atmosphere, clouds, shadows, SSR, SSAO, depth of field, bloomAtmospheric scattering, shadows, AO (WebGPU), bloom, clouds
Extension pointsCustom layers, addProtocolPrimitive, CustomShader, post-processingNew catalog types, init JSONFour API tiers, plugins, custom DescriptorsdefinePlugin, custom layers in the worker, three.js
Device careNative is the separate MapLibre NativeNothing specialMobile UIMobile: 8x coarser LOD, pixel ratio capped at 2Touch devices: 3 concurrent fetches, 160 MB GPU
LicenceBSD-3Apache-2.0Apache-2.0MIT or Apache-2.0GPL-3.0

Projection: how much of it is a sphere

The deepest difference is the projection. With projection set to "globe" in its style, MapLibre draws a sphere at low zoom and moves to Mercator as you zoom in. Underneath it is a Mercator map, and you can read the order of things: the sphere was added later as the view from far away. Cesium is the reverse: a WGS84 ellipsoid in 3D from the start, with 2D and Columbus view made by morphing the 3D scene. Terria keeps two engines and switches between them, Cesium for 3D and Leaflet for 2D.

Navara and ortho-earth have only the sphere. ortho-earth is written so that it cannot switch to a Mercator screen, and it reads MapLibre's projection as globe whatever it says. When a flat world map is needed it has Equal Earth (equal-area) separately, joined to the globe by an unfolding morph. Of the five, only ortho-earth never passes through the Web Mercator plane.

Threads: where the drawing happens

The free main thread that showed up in the benchmark comes from this difference. MapLibre and Cesium hand tile decoding and geometry building to workers, but draw on the main thread. Terria runs its React UI on that same thread as well. Navara runs its Rust core (Bevy ECS) in WebAssembly and sends heavy work such as terrain meshing to workers, but the per-frame ECS update and the three.js rendering stay on the main thread.

ortho-earth draws the map into an OffscreenCanvas in a render worker. What stays on the main thread is mostly input, UI and the label overlay. The price is that deck.gl's interleaved mode (sharing one GL context) is not available, and it falls back to overlaid. three.js and custom layers passed by URL are drawn inside the worker with the same camera and depth; passed as objects, they land on a separate canvas on the main thread and cannot share depth. That is the honest cost of drawing in a worker.

3D data

Cesium is far ahead in 3D Tiles. Its core reads the 1.0 and 1.1 formats, I3S, point clouds, Gaussian splats and voxels, and Cesium3DTileStyle and CustomShader let you style each feature. Since 1.142 it can read MVT by converting it to 3D Tiles, and 1.146 can drape it over terrain and 3D Tiles. Terria is Cesium inside, so it inherits all of this.

MapLibre has no 3D Tiles in its core; in the benchmark I overlaid deck.gl's Tile3DLayer. What it can read is whatever loaders.gl reads, and the MapLibre style cannot touch it. Navara reads b3dm, pnts and glb, but not yet i3dm or cmpt (there is a TODO in the source). ortho-earth reads b3dm, i3dm, pnts, cmpt, glb, I3S and COPC point clouds, with splats added by a plugin.

Vector tiles and labels

For 2D cartography MapLibre is the original, and the others are judged by how close they get. It has MVT and MLT, expressions, SDF text, collision, labels along lines, and a plugin for right-to-left scripts.

This is also where the five differ most. Cesium's MVT is a conversion to 3D Tiles, styled with Cesium3DTileStyle rather than a MapLibre style. Its LabelCollection has no map-style collision; overlapping labels are grouped with EntityCluster. Terria bakes MVT into images with protomaps, so text becomes a picture painted on the ground and lies flat when you tilt. Navara has a MapLibre style plugin, but support is partial, and it draws text with web fonts rather than glyph PBFs.

ortho-earth is checked against MapLibre's 139 official examples: 66 give the same picture, 50 the same answer, 21 run, and none fail to run. Labels are not GL SDF text but a Canvas2D overlay; collision is thinned so the winners stay stable, and positions are reprojected every frame. Vertical text and 26 languages feel like what you would expect from an engine that began with Japanese maps.

Time

Treating time as first-class is Cesium's tradition: Clock and Timeline, interpolated CZML positions, even imagery that changes over time. Terria turns this into a time slider for users, playing back WMS time dimensions and CSV time series as they are. MapLibre has no clock; the app expresses time by rewriting the style (deck.gl's TripsLayer has currentTime). Navara's time stops at the sun's position and glTF animation; there is no data clock.

ortho-earth moves the night side, stars, satellites (SGP4), interpolated CZML positions and trips on a single map.clock. The page for people coming from Cesium includes Clock and CZML in its side-by-side table.

Look

For photorealism Navara has gone furthest. Atmosphere, clouds, cascaded shadows, SSR (reflections on water), SSAO, depth of field, bloom and colour LUTs: three.js post-processing, used on a globe. Cesium is solid, with atmosphere, shadows, PBR and point-cloud EDL. ortho-earth draws shadows, AO, clipping and atmospheric scattering with WebGPU, and on WebGL2 you get the same map without them. MapLibre stays within a 2D map's sky, fog and light.

Finished product or building block

Terria alone is a finished product rather than a part. A catalog (close to 40 kinds of source, including WMS, ArcGIS, CKAN and SDMX), a workbench, feature-info templates, split-screen comparison, stories, share links and a mobile UI all come with it. That extra is why its JS heap was larger than Cesium's in the benchmark, and if you want a tool for presenting data, the weight is worth what it holds. Cesium's Viewer also bundles a timeline and geocoder widgets, but the other three hand you the map itself, and the app builds the UI.

Licence

One difference you cannot ignore when embedding: ortho-earth alone is GPL-3.0, while the other four are BSD, Apache or MIT. If you distribute a page that includes ortho-earth, that page's code falls under the GPL too. Any fair comparison should say so in a line.

Where ortho-earth stands

On breadth alone, ortho-earth covers the widest range of the five: it reaches for both MapLibre's 2D way of writing (style, expressions, queryRenderedFeatures, labels) and Cesium's 3D and time (3D Tiles, I3S, quantized-mesh, CZML, the clock). On top of that, analyses such as sun hours, viewshed and line of sight are in the core.

Against each original, though, it is still the one catching up in depth. Of MapLibre's 139 examples, 21 run but give a different picture or answer, and it has nothing yet like Cesium's voxels or 3D Tiles styling language, or Terria's years of catalog work. The interleaved limit that comes with drawing in a worker, and the GPL licence, are conditions for anyone choosing it.

In performance it sits in the same band as Cesium, and in features it takes the intersection of MapLibre and Cesium on a single sphere. That, I think, is the fair way to describe ortho-earth today.