@honua/sdk-js
v0.1.0-beta.0
Published
Honua JavaScript SDK — geospatial feature queries, Esri migration, and web mapping
Maintainers
Readme
Honua JS SDK
One geospatial client for GeoServices, OGC APIs, WMS/WMTS/WFS, STAC, and OData — with first-class TypeScript, a MapLibre runtime, and a drop-in ArcGIS migration path.
Release status: beta. The 20-entrypoint stable tier is frozen and guarded by an
API-surface gate; remaining pre-1.0 work is hardening, not surface change. See
docs/decisions/scope-split-and-1.0.md.
@honua/sdk-js is the JavaScript / TypeScript client for the Honua
geospatial platform. It speaks the open protocols your data already uses (Esri GeoServices,
OGC API Features / Tiles / Maps / Processes, STAC, WMS, WMTS, WFS 2.0, OData v4), exposes a
single protocol-neutral Dataset → Source → Query → Result contract on top of them, and
ships a MapLibre-first map runtime plus an Esri compatibility layer so existing ArcGIS apps
can migrate file-by-file.
📚 Hosted docs: honua-io.github.io/honua-sdk-js — quickstart, the full guide corpus, the TypeDoc API reference, and the demo gallery.
- Protocol-neutral. One
Source.query(...)call works against GeoServices, OGC, WFS, OData and friends. Capability misses throwHonuaCapabilityNotSupportedErrorinstead of returning empty results. - TypeScript first.
strict+verbatimModuleSyntax, exported types for every public symbol, declaration maps, and JSDoc on the public client surface. - Migrate, don't rewrite.
FeatureLayerCompat,MapImageLayerCompat,MapViewCompat,SceneViewCompat,WebMapCompat, and a safe codemod (honua-migrate) keep existing ArcGIS code running while you cut over. - Open runtime.
loadMapPackage(...)+HonuaMapRuntimerender a HonuaMapPackageon MapLibre GL JS. Cesium, kepler.gl, and OGC web-map sources are first-class.
What this is (and is not).
@honua/sdk-jsis a typed geospatial service client and migration toolkit — it is not a rendering engine. 2D rendering rides MapLibre GL JS and 3D rides Cesium, so the honest comparisons are the service-client libraries, not the renderers:
- vs
@esri/arcgis-rest-js— that's Esri's own client for Esri services only. Honua speaks GeoServices plus OGC API / WFS / WMS / WMTS / STAC / OData under one typed contract, with a capability model that throws instead of returning silently-empty results.- vs
esri-leaflet— dormant (last release 2025) and Leaflet-bound. Honua's esri-compat +honua-migratecodemod is an actively maintained migration path that targets MapLibre.- vs
openlayers/maplibre-gldirectly — pick those when you need a renderer and are happy hand-rolling service calls; pick Honua on top of MapLibre when you want the typed client, the ArcGIS migration path, or the server-authoredMapPackageruntime.The protocol clients work against any standards-speaking server — an existing ArcGIS Server/Online endpoint, any OGC API implementation, a STAC catalog. A Honua Server adds the server-authored
MapPackage, realtime, and AI surfaces, but it is the upgrade path, not the entry fee. When to use it standalone: if your data already sits behind an ArcGIS Server / ArcGIS Online endpoint, an OGC API Features server (pygeoapi, ldproxy, GeoServer OGC API), a WFS 2.0 server, a STAC API or static catalog, or an OData v4 service, use it today as a typed client andesri-leafletsuccessor — no server needed (the OGC API Features and STAC lanes discover the raw endpoint layout from the landing page; WFS follows the capabilities DCP URLs; setlocator.layoutfor non-facade servers — see the server-optional quickstart and the backend-agnostic capability matrix). Reach for a Honua Server when you need authored map packages, realtime, collaboration, MCP/AI, or the OGC API Tiles / Maps / Processes / Records families (still facade-bound today).
npm install @honua/sdk-jsBuild-less / CDN usage
For static sites, prototypes, or CSP-strict pages that can't run a bundler, a
prebuilt browser bundle is published under dist/browser/. Drop in the
minified IIFE build and use the global window.HonuaSDK:
<script src="https://cdn.jsdelivr.net/npm/@honua/sdk-js/dist/browser/honua-sdk.min.js"></script>
<script>
const client = new HonuaSDK.HonuaClient({ baseUrl: "https://your-honua-server.example" });
// window.HonuaSDK exposes the same public API as `import ... from "@honua/sdk-js"`.
</script>Or, for native ES module imports via an ESM CDN:
<script type="module">
import { HonuaClient } from "https://esm.sh/@honua/sdk-js/browser";
const client = new HonuaClient({ baseUrl: "https://your-honua-server.example" });
</script>The runtime peers (maplibre-gl, cesium, @bufbuild/*, @connectrpc/*) are
kept external — load them yourself when you need map rendering or gRPC
transport. See docs/browser-bundle.md for details.
Bundle size
Small and honest about size: every subpath entrypoint carries a min+gzip byte
budget that CI enforces on every PR (npm run verify:bundle-budgets), so drift
fails the build instead of shipping. Sizes are measured the way a consumer
builds — esbuild --bundle --minify, runtime peers external. A tree-shake guard
proves that importing a single symbol from the root doesn't drag the whole SDK
in.
| Entrypoint (gzip) | Size |
| --- | ---: |
| @honua/sdk-js/geocoding | 1.9 KiB |
| @honua/sdk-js/expr | 2.4 KiB |
| @honua/sdk-js/webmap | 5.9 KiB |
| @honua/sdk-js/style | 8.3 KiB |
| @honua/sdk-js/map | 16.2 KiB |
| @honua/sdk-js (root) | 108.3 KiB |
| { HonuaClient } only (tree-shake guard) | 47.2 KiB |
Full per-entrypoint table (min + gzip, generated, not hand-written):
docs/bundle-sizes.md. Refresh it with
npm run report:bundle-sizes.
60-second quickstart
No Honua server required. The first block below runs against a public Esri
GeoServices endpoint — no API key, no account, no infrastructure. The canonical
surface is protocol-neutral: build a Dataset over one or more Sources, then
call queryAll() (or query() / stream()).
import { createDataset, PROTOCOL_DEFAULT_CAPABILITIES } from "@honua/sdk-js/contract";
import { HonuaClient } from "@honua/sdk-js/honua";
// A public Esri Living Atlas FeatureServer — nothing of Honua's is running.
const client = new HonuaClient({
baseUrl: "https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis",
});
const dataset = createDataset({
id: "states",
client,
sources: [
{
id: "apportionment",
protocol: "geoservices-feature-service",
locator: {
url: "https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis",
serviceId: "2020_Census_State_Apportionment",
layerId: 0,
},
capabilities: PROTOCOL_DEFAULT_CAPABILITIES["geoservices-feature-service"],
},
],
});
const states = dataset.source("apportionment")!;
const result = await states.queryAll({
where: "Seats_2020 > 10",
outFields: ["NAME", "Total_Pop_2020", "Seats_2020"],
returnGeometry: true,
pagination: { limit: 100 },
});
console.log(`Loaded ${result.features.length} states`);The same code works against any GeoServices, OGC API Features, WFS, OData, or
STAC endpoint. Migrating from esri-leaflet? The raw GeoServices shape and the
esri-compat drop-in point at services.arcgis.com-style URLs unchanged:
const { features } = await client.queryFeatures({
serviceId: "2020_Census_State_Apportionment",
layerId: 0,
where: "1=1",
outFields: ["*"],
returnGeometry: true,
resultRecordCount: 25,
});Run the complete standalone app locally — public endpoint in, MapLibre map out:
npm install
npm run demo:standalone:mock # deterministic fixture lane (what CI runs)
npm run demo:standalone # live lane against the public Esri endpointSee docs/standalone-quickstart.md for the
guided server-optional walkthrough,
docs/standalone-capability-matrix.md
for the backend-agnostic vs server-enhanced breakdown, and
examples/standalone-quickstart/
for the committed source.
Add a Honua Server
A Honua Server is the upgrade
path, not the entry fee. It unlocks server-authored MapPackages
(loadMapPackage()), realtime subscriptions, collaboration / saved maps, and the
MCP + AI surfaces. Point the same code at a local server (docker compose up in a
honua-server checkout), and gate production reads on the compatibility check:
const { supported, reasons } = await client.checkCompatibility();
if (!supported) throw new Error(`Unsupported Honua server: ${reasons.join("; ")}`);The server-connected lane is the maplibre-quickstart
example (npm run demo:quickstart:mock); see
docs/quickstart.md and
docs/quickstart-troubleshooting.md.
Command-line client (honua)
Installing the SDK also installs a first-class honua CLI — the same
querying and catalog browsing without writing code. It wraps the SDK (no raw
HTTP, no URL-encoding, no f=json), prints readable tables by default, and adds
--json / --format geojson for machine output.
npm i -g @honua/sdk-js # or: npx @honua/sdk-js honua <command>
export HONUA_BASE_URL=https://demo.honua.io # anonymous reads on the public demo
honua services # list published services
honua layers maui-parcels # list a service's layers
honua query maui-parcels/1 --count
honua query maui-parcels/1 --where "tmk_txt LIKE '2%'" --limit 5
honua query maui-parcels/1 --bbox -156.7,20.7,-156.3,21.0 --format geojson
honua stac collections
honua geocode "1 Honolulu Pl, HI"
honua map export maui-parcels --bbox -156.7,20.7,-156.3,21.0 --size 800x600 -o maui.pngAuthentication resolves from --api-key, HONUA_API_KEY, or a saved
honua login. Run honua --help for the full command surface. This is the
recommended replacement for curl in docs and demos.
What you can build
| Demo | What it shows |
|------|---------------|
| maplibre-quickstart | MapLibre map + Honua FeatureServer query + popup inspection |
| react-quickstart | @honua/react provider + hooks + HonuaMap over the same fixture lane |
| storytelling-25d-map | 2.5D MapLibre storytelling, OGC overlays, route replay |
| kepler-analytics | kepler.gl analytics replay over fixture GeoJSON + KPIs |
| imagery-cog-quickstart | WMS GetMap, COG ImageServer tiles, exportImage previews |
| spatial-analytics-workbench | Honua Cloud AOI jobs + linked map/table/chart workbench |
| edit-workflow-demo | Optimistic create/update/delete with conflicts & attachments |
| geocoding-quickstart | Forward / reverse / typeahead via HonuaGeocodingClient |
| terrain-rgb-elevation | Terrain-RGB DEM tiles, point elevation, profile lookup |
| unified-ops-workspace | Composed incident-command + analysis workspace shell |
| cesium-route-playback | Cesium 3D route playback over one bounded Honua query |
Each example documents its own env surface, mock + live lanes, browser telemetry hooks, and Playwright smoke coverage. The 11 above are the flagship walkthroughs; another 11 runnable demos cover specialized workflows:
| Demo | What it shows |
|------|---------------|
| service-explorer | Catalog/service browse + linked-view explore over fixtures |
| migration-workbench | Interactive Esri → Honua migration with honua-migrate |
| ai-spatial-app-builder | LLM-driven spatial app builder using agent-tools |
| mcp-gis-assistant | MCP server exposing Honua tools to assistants |
| runtime-parity-showcase | Parity matrix demo across MapLibre / kepler / Cesium runtimes |
| realtime-incident-dashboard | SSE-backed realtime ops dashboard |
| geoprocessing-job-runner | Async GP job submit / poll / cancel |
| stac-imagery-browser | STAC search + COG preview |
| node-backend-quickstart | Server-side Honua client (Node) |
| app-bootstrap-basic | Minimal @honua/sdk-js/app bootstrap helper |
| web-components-basic | Custom-element gallery |
| arcgis-source-app | Drop-in ArcGIS migration target |
| standalone-quickstart | Server-optional front door: public Esri FeatureServer → MapLibre, no Honua server |
Mental model: Dataset → Source → Query → Result
Every Honua SDK — JavaScript, Python, .NET — speaks the same canonical
vocabulary. A Dataset groups one or more Sources. Each Source accepts a
protocol-neutral Query and returns a protocol-neutral Result. Operations the
canonical surface does not cover stay reachable through the typed
source.protocol(...) escape hatch. Method casing differs by language
(queryAll() / query_all() / QueryAllAsync()), the semantics do not.
Capability misses throw HonuaCapabilityNotSupportedError (under the default
strict policy) rather than silently returning empty results. See the
60-second quickstart above for the runnable shape; the
cross-language semantics, protocol/capability identifiers, language-binding
tables, and backwards-compatibility policy live in:
docs/sdk-surface-alignment.md— cross-language naming + semverdocs/shared-client-contract.md— contract designdocs/protocol-capability-matrix.md— what each protocol supports
Documentation
docs/quickstart.md— guided quickstart walkthroughdocs/guide.md— long-form reference (server compatibility, subpath entrypoints, OGC / WFS / OData cookbooks, MapLibre runtime, migration CLI, request/auth bridge)docs/errors.md— error class reference + retry policydocs/shared-client-contract.md—Dataset/Source/Query/Resultdesigndocs/protocol-capability-matrix.md— what each protocol supportsdocs/sdk-surface-alignment.md— cross-language naming & semver policydocs/maplibre-runtime.md—loadMapPackage()/HonuaMapRuntimedocs/react.md— React bindings (@honua/react): provider, hooks, and map componentsdocs/geometry.md—@honua/sdk-js/geometrycurated turf/proj4 ops (buffer/area/measure/simplify/reproject) + thegeometryEnginecompat shimdocs/studio-package-contracts.md— Studio package-family projections, validation envelope, capability manifest (@honua/sdk-js/studio)docs/features/README.md— capability snapshotINSTALL.md— install + subpath entrypoint table
AI assistants
Coding agents (Claude Code, Cursor, and compatible assistants) can discover and correctly use this SDK:
llms.txt— a curated llms.txt index of the docs, plusllms-full.txtwith the full corpus concatenated for single-fetch ingestion. Both are generated fromdocs/+README.md+ entrypoint JSDoc bynpm run docs:llms(freshness-checked in CI vianpm run verify:llms).- Agent skills under
skills/—honua-sdk-quickstart,honua-arcgis-migration, andhonua-mcp-setupload procedural instructions into Claude Code and compatible agents. Seeskills/README.mdfor installation. - MCP server —
@honua/mcp-serveris the platform-free geospatial MCP server: pointhonua-mcpat any public ArcGIS FeatureServer or OGC API endpoint (no Honua server required) and it exposes discovery, query, and analysis tools to assistants over the Model Context Protocol. Tools that need a Honua-only surface degrade gracefully with a structured "not available on this target" result. A Honua deployment's richer/mcpcatalog is the upgrade path viahonua-mcp-proxy. - Context7 —
context7.jsonregisters the library so Context7 serves current docs to coding agents; the submission steps are inskills/README.md.
Stability and versioning
- The SDK follows Semantic Versioning. The public contract is the set
of symbols reachable from the documented subpath entrypoints in
INSTALL.md. - Symbols marked
@experimentalin JSDoc may change in any minor release. The full table of stable and experimental subpaths lives inINSTALL.md. The short version:- Stable (semver-protected):
@honua/sdk-js,@honua/sdk-js/honua,@honua/sdk-js/contract,@honua/sdk-js/esri-compat,@honua/sdk-js/migration,@honua/sdk-js/runtime,@honua/sdk-js/expr,@honua/sdk-js/webmap,@honua/sdk-js/geocoding,@honua/sdk-js/exploration,@honua/sdk-js/interactions,@honua/sdk-js/filter-registry,@honua/sdk-js/style,@honua/sdk-js/map,@honua/sdk-js/realtime,@honua/sdk-js/react. - Experimental (subpath-only — not re-exported from the root barrels):
/agent-tools. - Application-platform surfaces (
/app,/app-controller,/app-workspace,/scene-workspace,/collaboration,/control-plane,/replica-sync,/share,/operate,/generated-app,/studio,/controls,/web-components,/operator,/operator/*) have moved to the separate@honua/app-platformpackage; the old@honua/sdk-js/*subpaths keep working for one minor behind a@deprecatedshim. The/consoleentrypoint was removed outright (no shim).
- Stable (semver-protected):
Support and lifecycle
We publish a lifecycle because a library you build on should tell you what it promises.
esri-leaflet never did, and "will this break under me?" is the question that decides adoption.
- Today (pre-1.0,
0.x). The stable tier — the subpath entrypoints listed under "Stable subpath entrypoints" inINSTALL.md— is where we invest compatibility effort, and it is guarded in CI by a public-API report (npm run verify:api-report): no symbol leaves or changes shape by accident. While we are on0.xa minor may still change a stable symbol, but only as a reviewed, called-out change — never silently. Symbols marked@experimentalin JSDoc may change in any minor. - At 1.0. The stable tier freezes under Semantic Versioning: breaking or removing a stable symbol requires a major version; minors are additive. Major versions are coordinated across the Honua SDK family (JavaScript, Python, .NET) so one semver line describes the contract on every platform.
- Application-platform surfaces move separately. App-shell, builder, and hosted-product
entrypoints are being extracted to a separate
@honua/app-platformpackage that versions at its own pre-1.0 cadence, so the client SDK can reach a frozen 1.0 without waiting on them. During the transition their old@honua/sdk-js/*subpaths keep working for one minor behind a@deprecatedre-export shim. Seedocs/decisions/scope-split-and-1.0.md. - What we don't promise. No security-backport window or LTS branch pre-1.0; fixes land on the current line. We will publish that policy when we cut 1.0.
More guides
Long-form reference material now lives in docs/guide.md:
- Demo apps in depth (each example's env contract, browser hooks, run lanes)
- Server compatibility baseline +
checkCompatibility()contract - Subpath entrypoints and the
@experimentaltier - Protocol cookbooks — OGC Features / Tiles / Maps / Processes / STAC, WMS / WMTS, WFS 2.0, OData v4
- Mixed Esri + OGC composition, streaming pagination, event lifecycle
- MapLibre
MapPackageruntime + Generated App preview runtime - Request/Auth bridge (interceptors, ArcGIS token + esri-request interop)
honua-migrateCLI, admin scanner, parity matrix, sample-corpus harness
Protocol-specific deep dives also live alongside the guide: see
docs/wfs.md, docs/ogc-api.md,
docs/maplibre-runtime.md,
docs/webmap-json-compatibility.md,
docs/protocol-capability-matrix.md, and
docs/migration-punch-list.md.
Contributing
This SDK ships from a single repository. The shipping package is @honua/sdk-js;
all subpath entrypoints in INSTALL.md live under that name.
See AGENTS.md for contributor instructions and the Specifica
issue format used for backlog items.
