h3-js
Uber's H3 hexagonal geospatial indexing system, compiled to pure JavaScript for Node and the browser.
Repository Health
Technical Analysis
h3-js is the official JavaScript port of Uber’s H3 library, a hierarchical hexagon-based geospatial indexing system originally built for ride-sharing analytics and now used broadly for spatial aggregation, visualization, and geofencing. The core C library is transpiled via Emscripten, so h3-js exposes the exact same operations as the native H3 API — converting coordinates to hexagon cells, walking hexagon grids, computing cell hierarchies, and generating hexagon coverage for polygons — with full parity and no native bindings to compile.
Because every H3 index is just a 64-bit hex string, the library slots cleanly into existing JSON pipelines, GeoJSON tooling, and databases without custom types. It ships as ES modules, CommonJS, and a UMD bundle for direct browser use, with first-class TypeScript definitions generated straight from the source.
What You Get
- Pure-JavaScript build of the H3 core library (via Emscripten) with full API parity — no native module compilation required
- Coordinate conversion functions (
latLngToCell,cellToLatLng,cellToBoundary) for mapping lat/lng points to hexagon cells and back - Grid traversal and hierarchy operations (
gridDisk,gridRing,cellToParent,cellToChildren,compactCells) for spatial aggregation and multi-resolution analysis - Polygon coverage utilities (
polygonToCells,cellsToMultiPolygon) that convert GeoJSON-style polygons into hexagon sets and back into outlines - TypeScript declaration files generated directly from the source, plus ES module, CommonJS, and UMD browser bundles
- A documented legacy compatibility layer for codebases migrating from the H3 v3 API to v4
Common Use Cases
- Aggregating ride, delivery, or event data into uniform hexagon cells for heatmaps and demand analysis
- Building geofences by converting service-area polygons into sets of H3 cells for fast point-in-region checks
- Powering hexbin map visualizations (e.g. deck.gl H3HexagonLayer) with consistent, multi-resolution spatial bins
- Deduplicating or clustering nearby geographic points by snapping them to a shared-resolution H3 cell
Under The Hood
Architecture - h3-js is a thin JavaScript binding layer over a C library compiled to WebAssembly/asm.js via Emscripten. lib/bindings.js declares the full table of native H3 functions and their C signatures, which lib/h3core.js wires up at load time using C.cwrap(...) against the compiled module imported from ../out/libh3. Each exported JS function (latLngToCell, gridDisk, polygonToCells, etc.) marshals JS values into the C module’s linear memory — allocating buffers sized via sizeOfH3Index(), sizeOfLatLng(), sizeOfCellBoundary() and friends — calls the corresponding bound C function, reads the result back out, and frees the buffer, with lib/errors.js translating native H3 error codes into thrown H3LibraryError/JSBindingError instances. A separate legacy.js/legacy-mapping.js layer re-exports the v3 function names as thin wrappers around the v4 API for projects migrating between major versions.
Tech Stack - The runtime surface has zero dependencies; everything needed to run ships in the compiled dist bundles (ES module, CommonJS, and UMD/browser builds via microbundle and rollup). The build toolchain is heavier: the H3 core is rebuilt from the upstream C library inside a pinned trzeci/emscripten Docker image (scripts/update-emscripten.sh), then bundled and type-checked with TypeScript (tsc --noEmit, strict mode) and linted with a legacy ESLint 4 + Prettier setup. Type declarations (dist/types.d.ts) are generated directly from the JSDoc-annotated source via tsc ... --emitDeclarationOnly, keeping the public API and its types mechanically in sync.
Code Quality - The project has an extensive test suite: test/h3core.spec.js and test/legacy.spec.js together exceed 1,700 lines, covering every exported function including edge cases (invalid indexes, pentagon cells, resolution domain errors) using tape, run through nyc for coverage and faucet for output formatting. Error handling is centralized and explicit — every native call path is wrapped so C-level error codes surface as typed JS errors with human-readable messages rather than silent failures or raw exit codes. Naming is consistent and mirrors the upstream H3 C API 1:1, which keeps the JS bindings predictable for anyone already familiar with H3’s C or Python bindings.
API Design - The public API favors plain data over custom classes: H3 indexes are always hex strings (or an optional [lower, upper] int-pair form for performance-sensitive code), coordinates are plain [lat, lng] tuples, and boundaries/polygons follow GeoJSON-adjacent conventions with an explicit formatAsGeoJson flag where ordering matters. Function names read as verbs on that data (cellToParent, gridDisk, polygonToCells), so the learning curve is mostly about learning H3’s own hexagon-grid vocabulary rather than the JS wrapper. The auto-generated README doubles as full API reference documentation with runnable examples for every function, which meaningfully lowers onboarding friction despite the conceptual depth of a hierarchical hexagonal grid system.
Used by 2 apps in this directory
Lightdash
Analytics · Data Engineering
The open-source Looker alternative that turns your dbt project's metrics and dimensions into governed, self-serve charts and dashboards — no license key required.
World Monitor
Monitoring · Analytics
Real-time global intelligence dashboard that fuses AI-synthesized news, geopolitical risk scoring, and infrastructure tracking into one open-source situational awareness platform.