h3-js: H3's hexagon grid in JavaScript, transpiled from C
h3-js provides a JavaScript version of H3, a hexagon-based geospatial indexing system.
At a glance
- What is it?
- h3-js is the Apache-2.0 JavaScript binding for Uber's H3 hexagonal geospatial index, built by transpiling the C core library with emscripten so the API matches exactly. It ships ES modules, CommonJS and UMD bundles, a legacy API shim and generated TypeScript types.
- Who is it for?
- h3-js fits a JavaScript or TypeScript service that needs a discrete, uniform-resolution hexagonal spatial index and wants the exact same results as the C library, which matters when indices are stored in a shared database. It does not fit a project that needs a pure JavaScript implementation, since the code is a transpiled C library compiled to WebAssembly, and it does not suit a team that needs the v3 API, whose function names mostly changed in v4.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A transpiled core, not a reimplementation
h3-js provides a pure-JavaScript version of the H3 Core Library, a hexagon-based geographic grid system, and the key sentence in the README explains how: the core library is transpiled from C using emscripten, offering full parity with the C API and highly efficient operations.
That is the defining architectural fact. This is not a JavaScript re-implementation of H3's algorithms, it is the C library itself compiled to WebAssembly, wrapped in a JavaScript API. The consequence is that an index produced by h3-js is the same index the C library produces, byte for byte, which is what makes it safe to store H3 indices in a database alongside rows written by the other language bindings.
The package description calls it a pure-JavaScript version of the H3 library, and the topics list names emscripten, geospatial, hexagon and spatial-indexing. The homepage is uber.github.io/h3 and the wider documentation is at h3geo.org.
The licence is Apache-2.0, the default branch is master, and the last push was on 2026-10-14. The version tags are v4.3.0 in August 2025, v4.4.0 in December 2025 and v4.5.0 in July 2026, and the package manifest version is 4.5.0.
The emscripten build is not incidental, it is the whole pipeline. The manifest has a `build-update-h3` script that runs `bash scripts/update-h3.sh` to pull in a new version of the C library, and a `build-emscripten` script that chains that with the Docker-based emscripten build. There is an `H3_VERSION` file at the repository root recording which upstream version is being used, and the README badge shows the H3 API version, v4.5.0, alongside the npm version.
Installing and importing, three ways
Installation is a single command:
npm install h3-jsThe library uses ES6 modules, and bundles for Node and the browser are built to the `dist` folder. The manifest sets `main` to `dist/h3-js.js`, `module` and `es2015` to `dist/h3-js.es.js`, and `umd:main` and `unpkg` to `dist/h3-js.umd.js`.
There are three import styles, and the difference between them matters for how you bundle. ES6 with a named import:
import {latLngToCell} from "h3-js";CommonJS with the whole library:
const h3 = require("h3-js");And a pre-bundled script for a page that does not have a build step, which exposes the library as an `h3` global:
<script src="https://unpkg.com/h3-js"></script>The naming of the functions changed substantially in H3 v4, and the README flags this prominently. The usage documentation applies to H3 v4, released on August 23, 2022, and for v3 docs there is a link to the latest v3.x.x release README. For breaking changes in v4 there is a pointer to the CHANGELOG and to the function migration guide, with the note that most function names have changed.
That is worth understanding before you port anything, because the renames are not cosmetic. The old `h3ToGeo` style names gave way to `cellToLatLng` and `cellToBoundary`, and a codebase written against v3 will not compile against v4 without a pass over the call sites.
The API surface: cells, rings and hierarchy
The API reference in the README is generated rather than written, which is visible from the fact that it lists constants and functions with their JSDoc signatures grouped under module names, including `UNITS` and `POLYGON_TO_CELLS_FLAGS`.
The core functions are the three you need to start. `latLngToCell(lat, lng, res)` converts a point to a cell index at a given resolution, `cellToLatLng(h3Index)` gives the centre of a cell back as a coordinate pair, and `cellToBoundary(h3Index)` gives the vertices. The README's example uses a resolution of 7 for a point in Mountain View and shows the resulting index.
The hierarchy functions are what make H3 more than a flat tiling. `cellToParent(h3Index, res)` moves up a resolution level, `cellToChildren` and `cellToChildrenSize` move down, `cellToCenterChild` and `cellToChildPos` and `childPosToCell` handle positional addressing within a parent, and `compactCells` and `uncompactCells` convert between a sparse set and a compact hierarchy.
The neighbourhood and geometry functions are `gridDisk`, `gridDiskDistances`, `gridRing` and `gridRingUnsafe`, the last of which presumably skips the safety checks on the ring. `polygonToCells` and `polygonToCellsExperimental` fill a polygon with cells, and `cellsToMultiPolygon` converts a set of cells back to a GeoJSON-style MultiPolygon outline.
There is also a validity and inspection layer: `isValidCell`, `isValidIndex`, `isPentagon`, `isResClassIII`, `getBaseCellNumber`, `getIndexDigit`, `getIcosahedronFaces` and `constructCell`, which together let you inspect and build an index by hand.
And there is a directed edge API for graph-like use: `areNeighborCells`, `cellsToDirectedEdge`, `getDirectedEdgeOrigin`, `getDirectedEdgeDestination` and `isValidDirectedEdge`. That is the part to reach for if you are modelling movement or flow between cells rather than just spatial aggregation.
How the package is built and typed
The build scripts in the manifest show the pipeline, and there is a lot of it because the package ships several API surfaces.
The documentation is generated with jsdoc2md from a partial template, using a helper that inserts the version, with the output written to README.md. That matches the comment at the top of the README, which says the README is generated from a template and that `doc-files/README.md.tmpl` is the file to edit. If you want to change the README you change the template, not the README.
The TypeScript definitions are generated too, and in two parts. `build-tsd-core` runs `tsc` over `lib/h3core.js` with `--noResolve --skipLibCheck --allowJs --declaration --emitDeclarationOnly`, outputting to `dist/types.d.ts`, followed by a postprocess script. `build-tsd-legacy` is a separate script for the legacy types, and `build-tsd` chains both.
The legacy API is a distinct product here. There are `legacy.js` and `legacy.d.ts` files at the repository root, a `build-legacy` script that runs `node scripts/build-legacy-api.js`, and a `build-legacy-types` script. The separate `bundle-cjs-browser` script aliases the output to a browser-specific build of the underlying library, `dist/libh3-browser`, which is a separate compilation target from the main one.
Bundling is done with microbundle, with three format targets, `umd`, `cjs` and `es`. The umd bundle is named `h3`, which is the global it exposes. The `cjs` and `es` bundles are built with `--no-compress`.
The repository also carries `benchmark/`, `test/`, `build/`, `out/` and `lib/`, plus `CHANGELOG.md`, `RELEASE.md`, `CONTRIBUTING.md` and a `NOTICE` file, and the tooling is configured with `.eslintrc`, `.prettierrc`, `.editorconfig` and a `.yvmrc` for the Yarn version.
The v3 to v4 rename, and who should care
The version history is short and the jump from v3 to v4 was the significant one, released on August 23, 2022.
The README's own note is that most function names have changed, with a link to the function migration documentation. The older naming convention was the `h3` prefix or camelCase with `Geo` in it, and the newer one is `cellTo` and `latLngToCell` style. The v3 docs are still reachable, in the README of the v3.7.2 tag, which is a practical way to check what a v3 call site used to be.
The API reference also contains a couple of functions that hint at the internals: `h3IndexToSplitLong` and `splitLongToH3Index`, with a `SplitLong` return type. They represent the 64-bit index as a lower and an upper half. A `h3-js` user rarely touches it, but it is the kind of detail that explains why a hexagon grid built on an icosahedron has some awkward cases.
`isPentagon` is the other one worth knowing, because pentagons are the distortion artefact of mapping a sphere onto a set of hexagons. They are the reason a hexagon grid on the globe is not perfectly uniform. Functions like `gridDisk` and `polygonToCells` have to handle them specially.
So the practical profile of this library is clear. It is a thin, faithful, fast binding, it is in active maintenance with three releases since August 2025, and its one sharp edge for an existing user is the v4 rename.
Editorial conclusion
h3-js fits a JavaScript or TypeScript service that needs a discrete, uniform-resolution hexagonal spatial index and wants the exact same results as the C library, which matters when indices are stored in a shared database. It does not fit a project that needs a pure JavaScript implementation, since the code is a transpiled C library compiled to WebAssembly, and it does not suit a team that needs the v3 API, whose function names mostly changed in v4. Before upgrading across the major version, read the CHANGELOG and the function migration guide, and pin the H3 version in the H3_VERSION file that the build reads.
Frequently asked questions
What is h3-js?
It is the pure-JavaScript version of the H3 Core Library, a hexagon-based geographic grid system from Uber. The core library is transpiled from C using emscripten, which gives full parity with the C API and efficient operations, and it can be used in Node or in the browser.
How do I install h3-js and import it?
Run `npm install h3-js`. You can then use an ES6 named import, `import {latLngToCell} from "h3-js"`, a CommonJS require, `const h3 = require("h3-js")`, or a pre-bundled script from unpkg that exposes an `h3` global.
What changed between H3 v3 and v4 in h3-js?
Most function names changed. The usage documentation applies to H3 v4, released on August 23, 2022, the older docs are in the README of the v3.7.2 tag, and the CHANGELOG and the function migration guide cover the breaking changes.
How is the h3-js README and its TypeScript types produced?
The README is generated with jsdoc2md from a template in doc-files, and the types are generated by running tsc over lib/h3core.js into dist/types.d.ts with a postprocess step, in separate core and legacy variants.
How does h3-js stay in sync with the C library?
The `build-update-h3` script runs scripts/update-h3.sh to pull in a new version of the C library, and `build-emscripten` chains that with the Docker-based emscripten build. The upstream version in use is recorded in the H3_VERSION file at the repository root.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/uber-h3-js)Was this useful?