Skip to content

Storage & sync

remap is local-first. A user who has never heard of remap gets working, still-remappable shortcuts with nothing but localStorage. Sync layers exist for users who want their keybindings to follow them — and cost you zero code either way.

Resolution order

For each shortcut id, the effective combo is the first layer that has an entry:

PriorityLayerWhereWhen it applies
1LocallocalStorage remap:<appId>:overridesAlways — set via the ⌘, overlay
2Devicehttp://127.0.0.1:53137/v1/config/:appIdremap menubar agent running (macOS app in progress)
3AccountGET /api/sync/config/:appId on the remap serverUser connected a sync token
4Defaultsthe keys you passed to useHotkeyAlways

An override value of null means the user disabled that shortcut.

Layers 2–3 load asynchronously with short timeouts (400ms local probe, 3s remote) and fail silently — no agent, no network, no problem. Writes fan out to every available layer, so remapping in one place propagates everywhere the user is connected.

The appId

Configs are keyed by appId (default: location.hostname). Pass an explicit stable id so localhost dev, previews, and production share one config:

tsx
<RemapProvider appId="myapp.com">

Account sync (cross-device)

  1. The user signs up at remap.harborapps.org and copies their sync token (rmp_…) from the dashboard.
  2. In your app, the token is stored via setSyncToken(token) (or directly under the remap:sync-token localStorage key). A built-in connect flow in the overlay is on the roadmap.
  3. From then on the library loads and saves their overrides on the remap server — the same config on every device and every remap-powered app.

The sync API is deliberately tiny — bearer tokens, never cookies, CORS-open:

GET  /api/sync/config/:appId   Authorization: Bearer rmp_…
PUT  /api/sync/config/:appId   { "overrides": { "editor.save": "mod+shift+s" } }

Opting out

tsx
<RemapProvider serverUrl={null} agentPort={null}>

disables all network layers — pure localStorage. Useful for demos, tests, and privacy-sensitive apps.

Free during beta · local-first usage stays free.