@shop-on/theme-dev-host
v0.4.0
Published
Local theme-editor dev server: serves the editor contract + proxies a theme's dev server behind one origin, so a theme runs locally and previews in a real admin theme-editor. Nucleus of the future theme CLI.
Readme
@shop-on/theme-dev-host
A local theme-editor dev server. It serves the editor contract (editor-loader,
draft read/write, template/settings) over a theme's local src/, and
reverse-proxies everything else to the theme's own dev server — behind one
origin a real admin theme-editor can bind to. So a theme runs and previews
locally while the platform spends ~zero compute (it never boots a storefront,
allocates a port, or stores an in-progress theme).
Self-contained: no Redis, no orchestrator dependency. This is the nucleus of the
future theme CLI (theme dev).
See docs/theme-dev-host.md for the architecture.
Quick start
# One command — starts the theme's dev server AND the gateway, wired together:
pnpm -C themes/care theme:editor
# gateway http://localhost:4101 (open this; ?preview=<sid> shows drafts)
# theme dev http://localhost:3002The gateway port is the single origin for both the editor API and the storefront
render. Ctrl-C stops both.
Each theme depends on @shop-on/theme-dev-host (workspace:*) and exposes
theme:editor → the theme-dev-host bin, which infers the theme from the directory
it runs in — so the command is identical for every theme.
Modes
| Command | What it runs |
| ---------------------------------------------------- | ------------------------------------------------------------- |
| pnpm -C themes/<name> theme:editor | theme dev server + gateway (the normal flow) |
| pnpm -C packages/theme-dev-host dev --theme <name> | gateway only (when the theme's pnpm dev is already running) |
Flags (theme:editor)
| Flag | Default | Purpose |
| ---------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <name> (positional) | inferred from the invoking theme dir | override the theme dir under themes/ |
| --port | 4101 | gateway port (the preview origin) |
| --theme-port | auto (read from the theme's vite.config) | the theme's own dev port |
| --slug / --install | <name> / devinstall | the (shop-handle, install-id) the gateway store-pins to — must match the connected install (install id is in the admin editor URL /themes/<install-id>/editor); defaults won't match a real store and 404 unknown store |
| --preset <handle> | the theme's current.preset | load that preset's settings into the editor and make it the target Save writes back to (load-state / save-state); a missing handle opens empty and Save creates it |
| --tunnel [provider] | off | expose the gateway publicly — cloudflared (default, no signup), ngrok, zrok |
| --public-url <url> | — | with --tunnel manual: front the gateway with any tunnel you run yourself |
| --env | dev | platform whose public key verifies editor tokens (dev/staging/prod) |
Editor write routes require a signature-verified RS256 JWT; pair a hosted-prod
admin with --env prod so the right key verifies it.
Saving back to source
The editor's draft is in-memory — "publish" clears it, it doesn't persist. To
commit your work, use the editor's Save (writes the current templates +
section groups + settings into the theme's src/) or Save as preset (writes
the current settings under a new named preset). Git is the checkpoint: Save →
src/ → commit. --preset <handle> picks which slot Save targets, so you can
load one state, tweak, and Save back to it — or branch to a fresh name with Save
as preset. Settings are merged into the preset map, so sibling presets are
never clobbered.
Without --tunnel the gateway is localhost-only. With --tunnel, paste the
printed public URL into the hosted admin theme-editor (actions menu → "Local
dev preview") to preview your local theme there — no backend or local admin
needed. HMR there dials ws://localhost:<theme-port>, so it only works in a
browser on the same machine as the dev server. See
docs/theme-dev-host.md.
Test
pnpm -C packages/theme-dev-host test