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.
| Group | Routes | Purpose |
|---|---|---|
| Tokens | GET /tokens/latest, GET /tokens/resolved, GET/POST /tokens/figma | The committed token set, the resolved map, and the Figma-exported snapshot the plugin pushes. |
| Preview | POST /preview, GET /preview/:id, GET /preview/latest, PUT /preview/:id, DELETE /preview/:id, GET /orgs/:orgId/preview/:id/subscribe | Open, read, edit, and tear down a live preview session; the last is the SSE stream an org-key connection can use instead of polling. |
| Verify | POST /verify, GET /verify/:id, GET /verify/latest, GET /verify/figma, GET/POST /verify/activity, POST /verify/app | Reconcile an inserted component's on-canvas geometry against the captured artifact. |
| Component graph | GET /artifacts, GET /artifact, GET /usages, GET /blast, POST /graft/plan | The 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. |
| Health | GET /health, GET /ready | Liveness 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-sitelocalhost:5173→localhost:7777), the Figma plugin's sandboxed iframe (opaquenullorigin, orhttps://www.figma.com), and non-browser callers (curl, a server-side SDK — noOriginheader 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. Readssorb.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 (nosorb.config.json, no token-file watching or Style Dictionary build — those are dev-only concerns), it listens on0.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 hostedbridge.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
@sorb/juicereference — the full CLI and route tables.- Hosted vs local — what changes between
sorb devand the hosted bridge. - Troubleshooting — connection and preview issues.
Works with Figma. Not affiliated with, or endorsed by, Figma. Figma is a trademark of Figma, Inc.