What it is
@nika-js/onlymap-native is the official React Native adapter for OnlyMap JS.
It packages the complete web runtime — every layer type, data format, live
transport, and validation rule — inside a secure WebView served from a
loopback-only host, and gives you <OmMap> and <OmLayer> components that
speak the same vocabulary as the web library. The adapter owns the JSON
bridge, the app lifecycle (background suspend, foreground resume), and
WebView renderer recovery.
It is not a native MapLibre renderer and not the web @nika-js/onlymap/react
adapter: it is the OnlyMap runtime itself, hosted natively. A 20-fixture
parity gate keeps the React Native surface byte-identical to the web React
adapter at the intermediate-representation level.
Support matrix
Install the package and follow the setup in its bundled
llms.txt (local
networking permission, cleartext-for-loopback exception, and the Metro config
extension for the packaged host assets):
The rules that differ from web
- Accessors are expression strings, never functions.
getPosition="[$lon, $lat]"crosses the JSON bridge;getPosition={(d) => ...}cannot and is rejected. - Props are camelCase JSX, not the web manifest’s kebab-case attributes.
- Everything crossing the bridge is finite plain JSON. Bulk data stays out
of the bridge: pass URLs (the full web format matrix works unchanged from a
URL inside the packaged host — GeoJSON, CSV, KML, GPX, FlatGeobuf, GeoArrow
including zstd, GeoParquet, Shapefile, range-requested COG), WebSocket
source="upsert"streams withstreamKey, orrefreshpolling. - Native UI lives beside the map, driven by the imperative handle and
useOmMapWatch; the web’s<om-widget>/<om-overlay>elements have no native components yet. emit()runs core-backed actions (fly-to,zoom-in,zoom-out,zoom-to-feature, registered custom actions) exactly as on the webMapController. DOM-manifest actions (toggle-layer,filter-layer, overlay/tooltip/story actions,set-basemap) deliberately warn and do nothing natively — express those through React props and state.
The imperative handle
A ref (oruseOmMap() in descendants) exposes the MapController surface,
all Promise-returning: flyTo, flyToBounds, zoomBy, setView,
getViewState, project, getSelection, emit, snapshot, stats,
data, dataInViewport, irSnapshot, reload, and injectPick.
injectPick is the consumer testing surface: a synthetic selection travels
the same code path as a real tap and reaches your per-layer
onClick/onHover, so interaction handling is testable in CI without a
device. reload() deliberately rebuilds the WebView renderer and replays
canonical state; repeated calls are harmless.
Lifecycle, verified on hardware
The adapter suspends rendering and live transports when the app backgrounds and restores them on foreground; WebView renderer loss replays configuration, the complete layer document, settled camera, and watches. These are tested claims, not intentions: the acceptance suite runs on an iOS simulator and an Android emulator in CI on every change, and on physical hardware the full flow suite is green — including a five-minute background against a live WebSocket feed (current data within seconds of returning), airplane-mode network loss with structured errors and unattended recovery, and bridge round-trip latency measured at ~8.5 ms median on a mid-range Android phone.Reference
- The package ships
llms.txt(the complete agent-facing authoring reference) and an installable agent skill — both inside the npm tarball. - Repository, examples, and acceptance evidence: github.com/NikaGeospatial/onlymap-native
- Licensing: commercial keys support app-scoped
appsclaims for packaged applications — see Licensing & Telemetry.