Run the bridge (sorb dev)

When you finish this page you have a bridge running on port 7777 serving your resolved tokens, and you know which command to reach for next — sorb serve to self-host, sorb check in CI, sorb handshake to invite a designer without an account. You need a sorb.config.json already in your project (npx sorb init, covered in Getting started).

Install and run

npm install -D @sorb/juice
sorb dev

sorb dev is the default command — running the bare sorb binary does the same thing. On startup it runs your Style Dictionary build once against the sources in sorb.config.json's tokenSources, writing .sorb/resolved.json, then watches those sources and re-runs the build on every change — there is no manual re-publish step during a session. It starts the bridge on http://localhost:7777 by default (-p/--port to override) and serves the freshly-built resolved map to the plugin and your app for as long as it's running.

What the bridge exposes

The bridge's public HTTP surface, grouped by what it's for. This is the subset customer-facing tooling touches — the @sorb/juice reference has the full public route table, with every method and response status.

GroupRoutesPurpose
TokensGET /tokens/latest, GET /tokens/resolved, GET/POST /tokens/figmaThe committed token set, the resolved map, and the Figma-exported snapshot the plugin pushes.
PreviewPOST /preview, GET /preview/:id, GET /preview/latest, PUT /preview/:id, DELETE /preview/:id, GET /orgs/:orgId/preview/:id/subscribeOpen, read, edit, and tear down a live preview session; the last is the SSE stream an org-key connection can use instead of polling.
VerifyPOST /verify, GET /verify/:id, GET /verify/latest, GET /verify/figma, GET/POST /verify/activity, POST /verify/appReconcile an inserted component's on-canvas geometry against the captured artifact.
Component graphGET /artifacts, GET /artifact, GET /usages, GET /blast, POST /graft/planThe captured Storybook index; where a token is used; its full alias chain; and a plan for re-pointing one component's token bindings onto another's.
HealthGET /health, GET /readyLiveness and readiness — the only two routes that need no key in hosted mode.

Create a preview by hand

Every write the plugin makes is a plain JSON request, so you can drive the bridge from a terminal or a test. Keys are custom-property names without the leading -- (the keys of your generated tokens.js); the body is stored and served back verbatim.

curl -s -X POST http://127.0.0.1:7777/preview \
  -H "content-type: application/json" \
  -d '{"button-primary-bg-default": "#e91e63"}'
# → {"id":"<id>","url":"?preview=<id>"}

curl -s http://127.0.0.1:7777/preview/<id>      # the same body back
curl -s -X DELETE http://127.0.0.1:7777/preview/<id>

Open your app at ?preview=<id> to see it applied; the preview lifecycle page explains what the SDK does with it from there. A body with a tokens key ({ "tokens": {...}, "darkTokens": {...} }) is the mode-aware shape used for dark mode.

Security posture

The local bridge is built to be safe by default:

  • It binds to 127.0.0.1 — nothing outside your machine can reach it.
  • Every write to /preview* goes through a same-site/CSRF guard: the leaf SDK (same-site localhost:5173 → localhost:7777), the Figma plugin's sandboxed iframe (opaque null origin, or https://www.figma.com), and non-browser callers (curl, a server-side SDK — no Origin header at all) are allowed; a real cross-site browser origin gets {"error": "cross-site write blocked"} with a 403. This guard runs in local mode only — the hosted bridge replaces it with API-key auth and scoped CORS.
  • Preview mode is off by default in the SDK and accepts previews only from bridge origins you allowlist.
  • Token values are validated before they're applied.

Don't enable preview mode in a production deployment against an untrusted bridge.

Local vs self-host

  • sorb dev — the command above. Reads sorb.config.json, builds and watches your local token sources, and runs the local (unauthenticated, 127.0.0.1-only) bridge. This is the free local loop.
  • sorb serve — runs the same bridge binary in hosted mode: config comes entirely from environment variables (no sorb.config.json, no token-file watching or Style Dictionary build — those are dev-only concerns), it listens on 0.0.0.0, and it requires a database to be configured. This is the container entry point Sorb Cloud runs; you'd only reach for it yourself to self-host the bridge rather than using the hosted bridge.sorbcloud.com. See Hosted vs local for what changes in hosted mode.

sorb check — CI drift detection

sorb check

Re-runs the Style Dictionary build and diffs the fresh snapshot against a baseline for drift, binding mismatches, off-role bindings, or deprecated tokens still referenced — exiting non-zero so a CI job can fail on it. --resolved, --baseline, --live, and --computed point it at specific snapshots; --no-build checks the existing snapshot without rebuilding; --format json for machine-readable output.

Inviting a designer (handshake)

To connect a designer without a hosted account, run:

sorb handshake --copy

This packs the bridge origin, app URL, and key into a single invite code (--pk to include a read-only hosted key, --exp to set an expiry, --copy to put it on the clipboard). Send the code; the designer pastes it into the plugin's Settings and it configures itself. See Connect flows.

Next

Works with Figma. Not affiliated with, or endorsed by, Figma. Figma is a trademark of Figma, Inc.