Best 3D globe npm packages for JavaScript and React
There is no honest single winner for every globe project. A decorative WebGL hero, a Canvas 2D data graphic, a tiled map, and a terrain engine solve different problems.
We tested nine current npm packages with the same deterministic data, viewport, browser, and measurement code. The goal is to help you choose the right renderer, not to make CanvasGlobe look fastest in every table.
Open the same-data benchmark lab to switch between all nine renderers and the 250, 1,000, and 5,000-marker workloads yourself. The lab uses the same seeded fixture as the measured results below.
Short answer
| Choose | Best fit | Main trade-off |
|---|---|---|
| CanvasGlobe | Canvas 2D globe and flat maps, no WebGL, keyboard-ready canvas, PNG and WebM export | Not a true 3D scene engine and not the fastest option for 5,000 animated markers |
| three-globe | A Three.js class with rich 3D geographic layers | Large Three.js dependency surface and direct server import failed in our Node check |
| globe.gl | High-level WebGL globe with points, arcs, labels, objects, and custom layers | Larger bundle and dependency graph than focused globe components |
| react-globe.gl | React applications that want globe.gl features | Adds React wrapper cost and still needs WebGL |
| Cobe | Small, polished decorative WebGL globes | Narrower data, map, accessibility, and export scope |
| CesiumJS | Terrain, imagery, 3D Tiles, and full geospatial applications | Much larger platform and operational scope |
| MapLibre GL JS | Tiled maps, geographic styling, labels, and globe projection | A map engine rather than a self-contained globe component |
| @wescld/dotted-map | Focused React dotted maps and globes | React-specific and intentionally narrower |
| Mappo | Compact dotted globes, SVG maps, and custom bodies | Region geometry and broader application behavior remain your responsibility |
Measured normal desktop workload
These results use 250 markers and 25 routes at 1280 by 720. Each value is the median of 20 measured runs after three warm-ups. Lower timing values are better.
| Package version | Renderer | Gzip bundle closure | Data render | Interaction frame | Transitive packages |
|---|---|---|---|---|---|
| canvas-globe 1.2.0 | Canvas 2D | 106.1 KB | 259.4 ms | 53.6 ms | 0 |
| three-globe 2.45.2 | Three.js and WebGL | 499.3 KB | 98.9 ms | 16.6 ms | 36 |
| globe.gl 2.46.2 | Three.js and WebGL | 528.6 KB | 110.2 ms | 16.6 ms | 44 |
| react-globe.gl 2.38.0 | React, Three.js, and WebGL | 597.7 KB | 214.1 ms | 16.6 ms | 52 |
| cobe 2.0.1 | WebGL | 6.6 KB | 57.6 ms | 16.6 ms | 0 |
| cesium 1.145.0 | WebGL geospatial engine | 1,080.7 KB | 305.2 ms | 16.6 ms | 28 |
| maplibre-gl 6.10.0 | WebGL map engine | 265.1 KB | 363.4 ms | 16.6 ms | 24 |
| @wescld/dotted-map 1.0.0 | React and Canvas 2D | 83.6 KB | 47.1 ms | 16.6 ms | 0 |
| mappo 0.3.0 | Canvas 2D and SVG | 16.2 KB | 62.6 ms | 16.6 ms | 0 |
CanvasGlobe was not the fastest renderer in this test. Its measured advantages were a zero-package dependency closure, no WebGL requirement, a labeled and focusable canvas in the default adapter, direct server import, and built-in image and video export APIs.
The bundle value is the minified gzip closure Vite associated with each isolated adapter. It is a controlled comparison, not a promise about your final application bundle.
5,000-marker emulated-mobile stress test
This workload uses 5,000 markers, 250 routes, a 390 by 844 viewport, and device scale factor 2. It is browser emulation on the test laptop, not evidence from a physical lower-end phone.
| Package | Data render median | Frame median | Heap median |
|---|---|---|---|
| CanvasGlobe | 1,476.4 ms | 365.1 ms | 8.9 MB |
| three-globe | 215.8 ms | 22.1 ms | 47.8 MB |
| globe.gl | 202.2 ms | 25.6 ms | 46.0 MB |
| react-globe.gl | 528.1 ms | 24.6 ms | 53.9 MB |
| Cobe | 84.2 ms | 16.7 ms | 5.8 MB |
| CesiumJS | 495.9 ms | 16.6 ms | 105.8 MB |
| MapLibre GL JS | 373.5 ms | 16.6 ms | 11.8 MB |
| @wescld/dotted-map | 52.0 ms | 16.9 ms | 40.6 MB |
| Mappo | 144.7 ms | 37.4 ms | 7.1 MB |
If your main requirement is thousands of independently animated objects, use a GPU-backed WebGL library. CanvasGlobe is better suited to smaller presentation and data-visualization workloads where Canvas 2D behavior, exports, and a controlled dependency surface matter more.
Server import and default accessibility surface
We imported each package directly in Node and inspected the default benchmark render for a labeled, focusable visualization. These are surface checks, not a WCAG audit and not a claim that an application cannot add its own semantics.
| Package | Direct Node import | Default canvas labeled and keyboard reachable |
|---|---|---|
| CanvasGlobe | Passed | Passed |
| three-globe | Failed: window is not defined | Not present in adapter |
| globe.gl | Failed: window is not defined | Not present in adapter |
| react-globe.gl | Failed: window is not defined | Not present in adapter |
| Cobe | Passed | Not present in adapter |
| CesiumJS | Passed | Partial: controls were reachable, canvas was not labeled |
| MapLibre GL JS | Passed | Passed |
| @wescld/dotted-map | Passed | Not present in adapter |
| Mappo | Passed | Not present in adapter |
Framework and SSR compatibility
A direct Node import is not the same as framework hydration. Browser-only packages can still work behind a client-only boundary, so we do not infer one result from the other.
For CanvasGlobe, we built production starters for all four frameworks, checked that the heading and canvas shell were present in server HTML, then opened the production output in Chrome. Each test required a rendered bitmap and no page, request, or hydration errors.
| Library | Primary package surface | Direct Node import | Next.js | Nuxt | SvelteKit | Angular |
|---|---|---|---|---|---|---|
| CanvasGlobe | Core plus first-party React, Vue, Svelte, Angular, and Web Component packages | Passed | Passed | Passed | Passed | Passed |
| three-globe | Imperative Three.js class | Failed: window is not defined | Not tested | Not tested | Not tested | Not tested |
| globe.gl | Imperative DOM component | Failed: window is not defined | Not tested | Not tested | Not tested | Not tested |
| react-globe.gl | React component | Failed: window is not defined | Not tested | Not tested | Not tested | Not tested |
| Cobe | Imperative WebGL canvas API | Passed | Not tested | Not tested | Not tested | Not tested |
| CesiumJS | Imperative geospatial engine | Passed | Not tested | Not tested | Not tested | Not tested |
| MapLibre GL JS | Imperative map engine | Passed | Not tested | Not tested | Not tested | Not tested |
| @wescld/dotted-map | React component | Passed | Not tested | Not tested | Not tested | Not tested |
| Mappo | Imperative Canvas 2D and SVG API | Passed | Not tested | Not tested | Not tested | Not tested |
Competitor hydration cells remain Not tested rather than being guessed from package documentation. The machine-readable framework evidence and four-framework browser report are committed with the test runner and Nuxt starter.
Export and network behavior
CanvasGlobe exposes direct PNG snapshot and WebM recording APIs. The other adapters could be captured through their browser canvas, but we did not count application-level canvas capture as a built-in library export API.
The benchmark deliberately used self-contained data and local assets. It made no claim that CesiumJS or MapLibre applications are normally network-free. Those engines commonly load imagery, terrain, styles, tiles, or 3D content from services. The raw request and transfer figures describe only the controlled local harness.
How the test works
- deterministic seed
20260919 - normal, dense, and stress workloads
- desktop and emulated-mobile viewports
- three warm-ups and 20 retained runs for every group
- disabled browser cache for cold-load runs
- median and p95 retained with every raw sample
- Chromium 153 on Windows, Intel Core i5-11320H, same machine for all runs
- 54 validated records and 1,080 retained runs
- no valid outliers removed
The complete adapters, lockfile, schema, raw samples, environment data, and generated report are available in the reproducible benchmark source.
When CanvasGlobe is the wrong choice
Choose another tool when you need:
- true camera perspective, scene depth, custom shaders, or arbitrary 3D objects
- terrain, satellite imagery, 3D Tiles, or a full GIS engine
- very large animated point clouds where GPU rendering is central
- the smallest possible decorative globe with only a few locations
- a permissively licensed production component instead of commercial terms
Choose CanvasGlobe when you need a no-WebGL Canvas 2D component with globe and flat projections, markers, routes, choropleths, keyboard behavior, reduced motion, and built-in export in one package. Try the playground with your own largest realistic dataset before purchasing.
If you are evaluating a paid production component, the premium interactive globe component guide collects the live product, commercial evidence, implementation scope, license path, and reasons not to buy in one review page.
Primary references
- CanvasGlobe benchmark source
- Interactive same-data benchmark lab
- three-globe repository
- globe.gl documentation
- react-globe.gl repository
- Cobe repository
- CesiumJS documentation
- MapLibre GL JS documentation
- @wescld/dotted-map repository
- Mappo repository
Last measured: September 19, 2026.