Verified 2026-10-06

OpenDesign: a runtime-adapter reference architecture

OpenDesign's runtime-adapter layer binds BYOK coding-agent CLIs to portable DESIGN.md contracts, enforcing harness-side quality gates on real exports.

Contents

    OpenDesign matters to harness builders less as a design tool than as a production-shaped reference for binding model-agnostic coding-agent CLIs to a fixed artifact contract, and the repository README frames it explicitly as an agent-native host with BYOK and portable output, which is the binding problem for anyone building one (README).

    OpenDesign is best read as an orchestrator-shaped host: Node 24 with Express, SSE streaming and better-sqlite3 behind a Next.js 16 App Router frontend on React 18 and TypeScript, wrapped in an Electron shell with a sandboxed renderer and sidecar IPC (README). One runtime registry serves the web app, the Electron desktop app, and the MCP/CLI surface, which is precisely the shape of a harness that must present a fixed contract to independently versioned binaries (architecture doc).

    The design catalog — 151 packages, hundreds of templates — is secondary to the mechanism: the host does not own the model, the agent loop, or the vendor. That separation is the same contract we examined when reading an agents-md file as an interface rather than a readme (agents-md as an engineering contract). The project describes itself as an agent-native, self-hostable design platform at open-design.ai, and the README remains the primary source for everything below.

    How This Review Was Researched

    This review draws on the GitHub repository, its raw README, the architecture and adapter documentation, the plugin spec, and the public issue tracker, with repository metrics captured as of the last push on 2026-10-06 (repo).

    This review is based on the repository source, documentation, and issue tracker — we did not run it hands-on.

    The repository reports 99,710 stars · 11,512 forks · 1,156 open issues · 302 watchers/subscribers · created 2026-04-28 · last push 2026-10-06 · Apache-2.0 · TypeScript (repo). Beyond the README, the corpus includes the architecture doc, the agent-adapters doc, the skills-protocol doc, the plugin spec, the QUICKSTART, the releases page, and linked third-party projects. Claims below are attributed to those documents, not to runtime observation.

    The Runtime-Adapter Layer: 27 Definitions, 26 Executables

    The adapter registry lives at apps/daemon/src/runtimes/ and contains 27 runtime definitions backed by 26 distinct local CLI executables, with byok-opencode sharing the OpenCode executable, while detection is PATH-scan based rather than configured, which means the host binds whatever versioned binaries it finds on the operator’s machine (README).

    The gap between 27 and 26 is the whole design in miniature: one definition (byok-opencode) reuses another’s binary, so the mapping from definition to executable is many-to-one rather than assumed one-to-one. PATH scanning keeps the host model-agnostic but hands version drift to the operator — acceptable for a desktop tool, an explicit hazard for a fleet.

    The agent-adapters doc is where the contract from runtime definition to spawnable binary and its BYOK fallback is specified, and it is the piece worth copying: a narrow adapter interface, a detection strategy, and a fallback path rather than a per-vendor fork.

    Two integration modes exist for external agents: skills, CLI and MCP for agents that consume OpenDesign, and native runtime adapters for agents OpenDesign launches. DeepSeek Harness is registered as a native runtime through its official dsh CLI, which places it under the second mode (DeepSeek Harness), which is a useful precedent if you want your harness to appear both as a host and as a guest.

    The Four-Plane Composition Model and the DESIGN.md Contract

    Composition splits into four planes — plugins, skills, design-templates, and design-systems — and every render reads the active design-system package’s DESIGN.md as a brand contract, so the model never authors identity from scratch, with legacy packages shipping DESIGN.md alone and newer ones adding manifest.json, tokens.css, components, assets, and provenance (README).

    Breadth as claimed by the README: 151 design-system packages · 100+ functional skills · 277 official plugins + 183 remixable reference examples · 15 deck templates × 36 themes · 26 coding-agent CLIs · 93 image prompt templates · 11 HyperFrames templates + 39 Seedance prompts (README).

    The catalogs are split on purpose: GET /api/skills serves the 100+ functional skills, GET /api/design-templates serves renderable templates, and treating them as one registry is the easiest way to misread those numbers. The skills-protocol doc defines the contract, aligned with how Claude Code consumes skills (Anthropic skills docs).

    Plugin manifests are open-design.json files carrying specVersion 1.0.0, semver, compat.agentSkills[].path, and an od block with kind (skill/scenario/atom/bundle), od.taskKind, od.mode, od.capabilities[], od.inputs[] (plugin spec). Restricted install grants only prompt:inject by default, so an install starts from the minimum capability set rather than the maximum (README). A DESIGN.md file functioning as a render-time contract mirrors the instruction-file-as-interface pattern we covered earlier (agents-md as an engineering contract).

    Execution Model and Dual Preview Path

    Filesystem-backed runs execute spawn(cli, [...], { cwd: managed project cwd }) and write canonical project files, while BYOK and plain-API runs return one complete <artifact> block parsed into a sandboxed srcdoc iframe, with live-artifact preview routes staying loopback-only, a deliberate split that keeps two very different execution models behind one artifact contract (README).

    The dual preview path is the reusable decision. Filesystem runs let the browser serve real files, so hot reload, inspection and diffing work normally; API runs have no files to serve, so the host extracts one self-contained <artifact> block and renders it in an iframe sandbox. Two trust postures, one preview surface — and the risk profile differs per path (sandboxing AI agent code execution).

    The BYOK proxy exposes POST /api/proxy/{anthropic,openai,azure,google,ollama,senseaudio}/stream returning SSE, with OpenAI-compatible presets including Atlas Cloud at https://api.atlascloud.ai/v1 (README). Routing provider traffic through a host-owned SSE proxy is the same pattern documented for production streaming architectures (LLM streaming architecture).

    Harness-Side Quality Gates: Artifact Lint and 5-Dim Self-Critique

    Quality enforcement sits on the harness side rather than the model side: a critique utility template emits a five-dimensional self-critique scoresheet used as a pre-emit gate, and a POST /api/artifacts/lint endpoint exists for programmatic checks, so neither vendor lock nor model cooperation is required for output gating (README).

    This is the most transferable piece. Because the gate lives after generation and before emit, it composes with any runtime in the registry: whatever the CLI produced is scored and linted before it becomes a previewable artifact. The critique is a structured artifact the harness holds and can decline on, rather than a free-form model self-assessment.

    The lint endpoint also gives you a seam for external enforcement — custom rules, structural checks on exported markup, or a review step in a pipeline — without forking the agent loop. It is the same “quality as harness property” argument that applies when a tool description is the trust boundary rather than the model (MCP tool description trust boundary).

    Export Pipeline: HTML, PDF, PPTX, ZIP, Markdown, and HyperFrames MP4

    The export surface covers HTML single-file with inlined assets, browser-print PDF that is deck-aware, PPTX via an agent-driven skill, ZIP, Markdown, and MP4, where HyperFrames takes agent-authored HTML, CSS, and GSAP and renders a deterministic MP4 through headless Chrome plus FFmpeg (HyperFrames).

    The formats matter because they are files, not screenshots: HTML single-file inlined assets · PDF browser print deck-aware · PPTX agent-driven skill · ZIP · Markdown · MP4 (README). Determinism comes from the renderer, not the model — the agent authors animation, the pipeline frames it — so the MP4 path renders HTML, CSS and GSAP rather than generating video pixels. Binaries ship through the releases page.

    Security Posture and Operator Tradeoffs

    The daemon binds 127.0.0.1 by default, blocks RFC1918, link-local, CGNAT and cloud-metadata targets through an SSRF guard, and exposes an OD_ALLOWED_INTERNAL_HOSTS opt-out accepting exact hosts only, empty by default, plus a macOS/WSL2 PATH collision where Apple’s octal-dump od shadows the OpenDesign CLI (README).

    Guard semantics are worth stating exactly: OD_ALLOWED_INTERNAL_HOSTS takes exact hosts with no CIDR support (CIDR entries are dropped with a warning), bracketed IPv6 is required, download URLs returned inside upstream responses stay blocked, and the allowlist is empty by default. The guard is a deny-list of address classes with a narrow, operator-authored escape hatch.

    Loopback posture is similarly explicit: credentials and live-artifact preview routes stay loopback-only, MCP is read-only by default, and LAN exposure requires both OD_BIND_HOST and OD_ALLOWED_ORIGINS (README). Two operator hazards remain: there is no prebuilt Linux desktop artifact, tracked in issue #4368, and on macOS/WSL2 the od PATH collision can shadow the CLI unless you point MCP config at absolute paths.

    OpenDesign vs Claude Design, Figma, and Lovable/v0/Bolt

    The README ships its own four-way comparison against Claude Design, Figma, and Lovable/v0/Bolt across eight criteria covering open source, self-hosting, agent reach, DESIGN.md depth, plugin breadth, HyperFrames, repo refresh, and minimum billing, all written by OpenDesign’s own maintainers as positioning copy (README).

    The table is transcribed from OpenDesign’s own README comparison; it is vendor-authored marketing copy and should be attributed as such.

    Claude DesignFigmaLovable / v0 / BoltOpenDesign
    Open sourceNoNoNoYes (Apache-2.0)
    Self-host / desktopNoNoNoYes (macOS + Windows + Docker + Vercel web)
    Agent-native (runs in your CLI)Anthropic onlyNoCloud agent onlyYes (claimed “25 CLIs + BYOK”; registry shows 26 executables / 27 definitions)
    Brand-grade DESIGN.mdProprietaryTheme JSONLimited tokensYes (151 systems shipped)
    Skills / plugins / templatesClosedPlugin storeClosedYes (100+ functional skills · rendering templates · 277 plugins)
    HyperFrames (HTML→MP4)NoNoNoYes (first-class)
    Refresh an existing repo to brandNoNoNoYes (via agent + DESIGN.md)
    Minimum billingPro / Max / TeamPro / OrgPro / TeamBYOK · any compatible endpoint

    Read against the registry, the agent-native row is where the marketing and the source diverge — the table claims 25 CLIs while the runtime directory shows 26 executables and 27 definitions. The billing row is reproduced as vendor copy: it lists plan tiers and ends at “BYOK · any compatible endpoint” rather than at a price.

    Unshipped Roadmap Gaps and Internal Inconsistencies

    The roadmap lists comment-mode surgical edits as partially shipped, the AI tweaks panel as not implemented despite a tweaks utility template, and the Plugin SDK plus od plugin {add,list,remove,test,publish} CLI as absent, while the README comparison says 25 CLIs against a registry of 26 executables and 27 definitions (README).

    Other gaps: npx od init is not yet available; Figma/Pencil → React/Next/Vue migration plugins are in alpha; the refresh-existing-codebase plugin is unshipped. Two numeric discrepancies should be reported, not reconciled: 25 CLIs (README comparison table) versus 26 distinct executables / 27 runtime definitions (runtime registry and breadth line), and 277 official plugins (breadth line) versus 261 official plugins (the README’s v0.8.0 roadmap entry). Both look like as-of-version differences in a fast-moving README, but neither is resolved by the sources.

    The Bottom Line

    For infrastructure engineers, OpenDesign is worth studying as a runtime-adapter and artifact-contract reference rather than adopting wholesale, because its daemon stack, dual preview path, and harness-side gates answer the binding questions without requiring you to adopt its design catalog or its vendor comparisons (repo).

    Copy the shape, not the product: a PATH-detected adapter registry behind one spawn signature, a single <artifact> contract with two preview trust postures, an emit-side lint plus scored self-critique you own, and exports that never depend on the model that produced them. What you should not copy unexamined is the operational surface — the SSRF opt-out semantics, the loopback-only assumptions, and the desktop distribution gaps.

    FAQ

    Three questions recur among harness engineers evaluating OpenDesign — whether it is safe to self-host inside a corporate network, how BYOK differs from running the same agent in a terminal, and what the sidecar EVAL verb plus the SSRF opt-out actually expose to an operator (README).

    Is OpenDesign production-ready for self-hosting in an internal network?

    The defaults are conservative — 127.0.0.1 binding, read-only MCP, credentials and live-artifact preview routes loopback-only — but LAN exposure is an explicit operator action requiring OD_BIND_HOST plus OD_ALLOWED_ORIGINS, and there is no prebuilt Linux desktop artifact (issue #4368). Docker and web deployment exist as documented paths, but treat the SSRF allowlist and the /usr/bin/od collision as mandatory pre-deployment review items rather than edge cases.

    How does BYOK differ from running the same agent in my own CLI?

    The two paths are different contracts, not the same loop in two wrappers. A filesystem-backed run spawns the detected CLI and lets it write canonical project files the host previews; a BYOK run instead sends the request through POST /api/proxy/{anthropic,openai,azure,google,ollama,senseaudio}/stream, returns a single <artifact> block into a sandboxed iframe, and passes the pre-emit critique gate and POST /api/artifacts/lint before anything renders. Neither the preview contract nor the DESIGN.md binding is present when you run that CLI in a terminal yourself (README).

    What are the real risks of the sidecar EVAL verb and the SSRF opt-out?

    The sidecar IPC channel is exactly STATUS · EVAL · SCREENSHOT · CONSOLE · CLICK · SHUTDOWN, so EVAL and CLICK give the host real driving power inside the renderer — a capability you must scope if you extend it. The SSRF opt-out is narrow (exact hosts, empty by default, no CIDR, bracketed IPv6, upstream-returned download URLs still blocked), but it converts a deny-list into operator policy, and misconfiguration there is the fastest way to widen the daemon’s reach (README).

    • NiteAgent — AI agent development, frameworks, and production patterns

    Cross-links automatically generated from CodeIntel Log.