kotao theme dev spawns Astro dev against the storefront runtime, but with your theme swapped in as the active one. Hot reload on save, ctrl-c to stop.
What it actually does
When you run kotao theme dev inside a theme project, the CLI:
- Validates the project (
theme.json+kotao.theme.tomlpresent, slugs match, semver valid). - Finds the runtime —
apps/web/sites-theme-runtime/somewhere up the directory tree, or--runtime=<path>if you pass it explicitly. - Swaps the runtime’s active theme — rewrites
<runtime>/src/active-theme.tsto import your theme by absolute path. - Spawns
astro devfrom inside the runtime, stdio inherited. - Restores the runtime’s
active-theme.tson ctrl-c or process exit so the runtime checkout isn’t left dirty.
Step 5 is load-bearing: a leaked dirty active-theme.ts would cause the runtime’s CI to either commit your local path (which doesn’t resolve on the build cluster) or fail typecheck. The CLI registers SIGINT and SIGTERM handlers that run the restore even when astro is killed.
Flags
| Flag | Default | Notes |
|---|---|---|
--runtime=<path> | auto-detect | Where sites-theme-runtime/ lives. Required when not in a monorepo checkout. |
--port=<n> | 4321 | Astro dev port. |
--host=<addr> | 127.0.0.1 | Loopback by default; --host=0.0.0.0 to expose on the LAN. |
KOTAO_THEME_RUNTIME=<path> is an alternative to --runtime if you’d rather not pass it every invocation.
Hot reload
Astro’s dev server watches your project files and rebuilds on save. The reload covers:
.astrofiles (sections, layouts) → instant.cssfiles → instant.ts/.jsfiles (helpers, the theme entry) → fast HMRtheme.json→ requires a manual page refresh
A clean reload means your renderer logged no errors and the section schemas accepted the rendered data. A red overlay in the browser means one of those failed; the message tells you which.
When theme dev errors out
”Couldn’t find a sites-theme-runtime checkout”
You’re outside the surreal-kotao monorepo. Phase 4C ships the in-repo path; pass --runtime=<path> to a checkout you’ve cloned. Phase 4D will package a runtime as @kotao/sites-theme-runtime on npm so this isn’t required.
”Couldn’t find <theme>/src/theme.ts”
Every theme must export its Theme object as the default from src/theme.ts. The scaffold (kotao theme init) writes this for you; if you started from someone else’s theme that omitted it, add one matching the SDK README’s shape.
Astro renders a section as [object Object] or empty
Your renderer received data that doesn’t match the expected shape. Two common causes:
- The
dataprop typing isn’t picking up the right type. Make sureProps extends SectionRendererProps<"<section-type>">matches the section type exactly. - You’re indexing into
data.someFieldthat’soptionalin the schema andundefinedfor this section instance. Add an{x && <…>}guard.
Dirty active-theme.ts after a crash
If theme dev was force-killed (kill -9, OS reboot mid-dev), the cleanup handlers didn’t run. Inside the runtime checkout:
git checkout src/active-theme.ts
The committed version always imports the linen first-party theme — restoring to that puts the runtime back into its default state.
kotao theme dev doesn’t render real workspace content
Today, theme dev renders the scaffolded fixture data — useful for iterating on visuals but not for verifying behavior against your actual content. The plan covers a --with-workspace=<slug> flag that mints a preview token and feeds real RenderDocuments into the runtime; that’s deferred to a follow-up.
In the meantime, kotao theme push is the way to verify against real content: bump the version, push, and apply the new theme to a staging site.