English Β· Deutsch Β· ζ₯ζ¬θͺ
Run the full product locally.
- Node.js:
~24(Node 24.x). The repo enforces this throughpackage.json#engines. - pnpm:
10.33.x. The repo pinspnpm@10.33.2throughpackageManager; use Corepack so the pinned version is selected automatically. - OS: macOS, Linux, and WSL2 are the primary paths. Windows native should work for most flows, but WSL2 is the safer baseline.
- Optional local agent CLI: Claude Code, Codex, Devin for Terminal, Gemini CLI, OpenCode, Cursor Agent, Qwen, GitHub Copilot CLI, etc. If none are installed, use the BYOK API mode from Settings.
nvm / fnm are optional convenience tools, not required project setup. If you use one, install/select Node 24 before running pnpm:
# nvm
nvm install 24
nvm use 24
# fnm
fnm install 24
fnm use 24Then enable Corepack and let the repo select pnpm:
corepack enable
corepack pnpm --version # should print 10.33.2corepack enable
pnpm install
pnpm tools-dev run web # starts daemon + web in the foreground
# open the web URL printed by tools-devFor the desktop shell and all managed sidecars in the background:
pnpm tools-dev # starts daemon + web + desktop in the backgroundOn first load, the app detects your installed code-agent CLI (Claude Code / Codex / Devin for Terminal / Gemini / OpenCode / Cursor Agent / Qwen), picks it automatically, and defaults to web-prototype skill + Neutral Modern design system. Type a prompt and hit Send. The agent streams into the left pane; the <artifact> tag is parsed out and the HTML renders live on the right. When it finishes, click Save to disk to persist the artifact under ./.od/artifacts/<timestamp>-<slug>/index.html.
The Design system dropdown ships with 129 design systems β 2 hand-authored starters (Neutral Modern, Warm Editorial), 70 bundled product systems, and 57 design skills sourced from awesome-design-skills. Pick one to skin every prototype in that brand's aesthetic.
The Skill dropdown groups by mode (Prototype / Deck / Template / Design system) and shows the default skill per mode with a Β· default suffix. Bundled skills:
- Prototype β
web-prototype(generic),saas-landing,dashboard,pricing-page,docs-page,blog-post,mobile-app. - Deck / PPT β
simple-deck(single-file horizontal swipe) andmagazine-web-ppt(theguizang-pptbundle fromop7418/guizang-ppt-skillβ default for deck mode, ships its own assets/template + 4 references). Skills with side files get an automatic "Skill root (absolute)" preamble so the agent can resolveassets/template.htmlandreferences/*.mdagainst the real on-disk path instead of its CWD.
Pair a skill with a design system and a single prompt produces a layout-appropriate prototype or deck in the chosen visual language.
pnpm tools-dev # daemon + web + desktop in the background
pnpm tools-dev start web # daemon + web in the background
pnpm tools-dev run web # daemon + web in the foreground (e2e/dev server)
pnpm tools-dev restart # restart daemon + web + desktop
pnpm tools-dev restart --daemon-port 7457 --web-port 5175
pnpm tools-dev status # inspect managed runtimes
pnpm tools-dev logs # show daemon/web/desktop logs
pnpm tools-dev check # status + recent logs + common diagnostics
pnpm tools-dev stop # stop managed runtimes
pnpm --filter @open-design/daemon build # build apps/daemon/dist/cli.js for `od`
pnpm build # production build + static export to apps/web/out/
pnpm typecheck # workspace typecheckpnpm tools-dev is the only local lifecycle entry point. Do not use the removed legacy root aliases (pnpm dev, pnpm dev:all, pnpm daemon, pnpm preview, pnpm start).
During local development, tools-dev starts the daemon first, passes its port into apps/web, and apps/web/next.config.ts rewrites /api/*, /artifacts/*, and /frames/* to that daemon port so the App Router app can talk to the sibling Express process without CORS setup.
Image, video, audio, and HyperFrames skills call the local od CLI through environment variables injected by the daemon when it spawns an agent:
OD_BINβ absolute path toapps/daemon/dist/cli.js.OD_DAEMON_URLβ the running daemon URL.OD_PROJECT_IDβ the active project id.OD_PROJECT_DIRβ the active project's file directory.
If media generation fails with OD_BIN: parameter not set, apps/daemon/dist/cli.js missing, or failed to reach daemon at http://127.0.0.1:0, rebuild the daemon CLI and restart the managed runtime:
pnpm --filter @open-design/daemon build
pnpm tools-dev restart --daemon-port 7457 --web-port 5175
ls -la apps/daemon/dist/cli.js
curl -s http://127.0.0.1:7457/api/healthThen open the project from the Open Design app again instead of resuming an old terminal agent session. A daemon-spawned agent should see values like:
echo "OD_BIN=$OD_BIN"
echo "OD_PROJECT_ID=$OD_PROJECT_ID"
echo "OD_PROJECT_DIR=$OD_PROJECT_DIR"
echo "OD_DAEMON_URL=$OD_DAEMON_URL"
ls -la "$OD_BIN"OD_DAEMON_URL must be a real daemon port such as http://127.0.0.1:7457, not http://127.0.0.1:0. The :0 value is only an internal "pick a free port" launch hint and should not leak into agent sessions.
For the daemon-only production mode, the daemon serves the static Next.js export itself at http://localhost:7456, so no reverse proxy is involved.
If you place nginx in front of the daemon, keep SSE routes unbuffered and uncompressed. A common failure is the browser console showing net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK) after 80-90 seconds because nginx gzip on buffers chunked SSE responses even when the daemon sends X-Accel-Buffering: no.
location /api/ {
proxy_pass http://127.0.0.1:7456;
proxy_buffering off;
gzip off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}| Mode | Picker value | How a request flows |
|---|---|---|
| Local CLI (default when daemon detects an agent) | "Local CLI" | Frontend β daemon /api/chat β spawn(<agent>, ...) β stdout β SSE β artifact parser β preview |
| Anthropic API (fallback / no CLI) | "Anthropic API Β· BYOK" | Frontend β @anthropic-ai/sdk direct (dangerouslyAllowBrowser) β artifact parser β preview |
Both modes feed the same <artifact> parser and the same sandboxed iframe. The only thing that differs is the transport and the system-prompt delivery (local CLIs have no separate system channel, so the composed prompt is folded into the user message).
For every send, the app builds a system prompt from three layers and sends it to the provider:
BASE_SYSTEM_PROMPT (output contract: wrap in <artifact>, no code fences)
+ active design system body (DESIGN.md β palette/type/layout)
+ active skill body (SKILL.md β workflow and output rules)
Swap the skill or the design system in the top bar and the next send uses the new stack. Bodies are cached in-memory per session so this is a single daemon fetch per pick.
open-design/
βββ apps/
β βββ daemon/ # Node/Express β spawns local agents + serves APIs
β β βββ src/
β β βββ cli.ts # `od` bin entry
β β βββ server.ts # /api/* + static serving
β β βββ agents.ts # PATH scanner for claude/codex/devin/gemini/opencode/cursor-agent/qwen/copilot
β β βββ skills.ts # SKILL.md loader (frontmatter parser)
β β βββ design-systems.ts # DESIGN.md loader
β β βββ sidecar/ # tools-dev daemon sidecar wrapper
β β βββ tests/ # daemon package tests
β βββ web/ # Next.js 16 App Router + React client
β βββ app/ # App Router entrypoints
β βββ src/ # React + TypeScript client/runtime modules
β β βββ App.tsx # orchestrates mode / skill / DS pickers + send
β β βββ providers/ # daemon + BYOK API transports
β β βββ prompts/ # system, discovery, directions, deck framework
β β βββ artifacts/ # streaming <artifact> parser + manifests
β β βββ runtime/ # iframe srcdoc, markdown, export helpers
β β βββ state/ # localStorage + daemon-backed project state
β βββ sidecar/ # tools-dev web sidecar wrapper
β βββ next.config.ts # tools-dev rewrites + prod apps/web/out export config
β βββ desktop/ # Electron runtime, launched/inspected by tools-dev
βββ packages/
β βββ contracts/ # shared web/daemon app contracts
β βββ sidecar-proto/ # Open Design sidecar protocol contract
β βββ sidecar/ # generic sidecar runtime primitives
β βββ platform/ # generic process/platform primitives
βββ tools/dev/ # `pnpm tools-dev` lifecycle and inspect CLI
βββ e2e/ # Playwright UI + external integration/Vitest harness
βββ skills/ # SKILL.md β drops in from any Claude Code skill repo
β βββ web-prototype/ # generic single-screen prototype (default for prototype mode)
β βββ saas-landing/ # marketing page (hero / features / pricing / CTA)
β βββ dashboard/ # admin / analytics dashboard
β βββ pricing-page/ # standalone pricing + comparison
β βββ docs-page/ # 3-column documentation layout
β βββ blog-post/ # editorial long-form
β βββ mobile-app/ # phone-frame single screen
β βββ simple-deck/ # minimal horizontal-swipe deck
β βββ guizang-ppt/ # magazine-web-ppt β bundled deck/PPT default
β βββ SKILL.md
β βββ assets/template.html
β βββ references/{themes,layouts,components,checklist}.md
βββ design-systems/ # DESIGN.md β 9-section schema (awesome-claude-design)
β βββ default/ # Neutral Modern (starter)
β βββ warm-editorial/ # Warm Editorial (starter)
β βββ README.md # catalog overview
β βββ β¦129 systems # 2 starters Β· 70 product systems Β· 57 design skills
βββ scripts/sync-design-systems.ts # re-import from upstream getdesign tarball
βββ docs/ # product vision + spec
βββ .od/ # runtime data (gitignored, auto-created)
β βββ app.sqlite # projects / conversations / messages / tabs
β βββ artifacts/ # one-off "Save to disk" renders
β βββ projects/<id>/ # per-project working dir + agent cwd
βββ pnpm-workspace.yaml # apps/* + packages/* + tools/* + e2e
βββ package.json # root quality scripts + `od` bin
- "no agents found on PATH" β install one of:
claude,codex,devin,gemini,opencode,cursor-agent,qwen,copilot. Or switch to "Anthropic API Β· BYOK" in the top bar and paste a key in Settings. - daemon 500 on /api/chat β check the daemon terminal for the stderr tail; usually the CLI rejected its args. Different CLIs take different argv shapes; see
apps/daemon/src/agents.tsbuildArgsif you need to tweak. - media generation says
OD_BINis missing or daemon URL is:0β run the media dispatcher checks above. Do not resume the old CLI session; reopen the project from the Open Design app so the daemon can inject freshOD_*variables. - Codex loads too much plugin context β start Open Design with
OD_CODEX_DISABLE_PLUGINS=1 pnpm tools-devto make daemon-spawned Codex processes run with--disable plugins. - artifact never renders β the model produced text without wrapping in
<artifact>. Confirm the system prompt is going through (check daemon log) and consider switching to a more capable model or a stricter skill.
This Quickstart is the runnable seed of the spec in docs/. The spec describes where this grows (see docs/roadmap.md). Highlights:
docs/architecture.mddescribes the shipped stack: Next.js 16 App Router in front, local daemon behind it, andapps/web/next.config.tsrewrites in dev to keep the browser talking to the same/apisurface.docs/skills-protocol.mddescribes the fullod:frontmatter (typed inputs, sliders, capability gating). This MVP readsname/description/triggers/od.mode/od.design_system.requiresonly β extendapps/daemon/src/skills.tsto add the rest.docs/agent-adapters.mdforesees richer dispatch (capability detection, streaming tool-calls). Ourapps/daemon/src/agents.tsis a minimal dispatcher β enough to prove the wiring.docs/modes.mdlists four modes: prototype / deck / template / design-system. We ship skills for the first two; the picker already filters bymode.