OD '26
All Chapters

PART II: WORKING IN OPEN DESIGN · SECTION 08

The Preview and Export Pipeline

Sandboxed iframe to HTML, PDF, PPTX, image, ZIP, and MP4

Reading time

24 min

Chapter

08

The Preview and Export Pipeline

Sandboxed iframe to HTML, PDF, PPTX, image, ZIP, and MP4

The sandboxed preview keeps generated code from touching your system, and the export pipeline turns that same artifact into shippable files — sandbox in, files out.

8.1 Why the Preview Is Sandboxed

Sandboxed iframe preview architecture

Every artifact Open Design generates runs inside a locked-down iframe before you ever export it. The lock is intentional, and removing it would undermine the central promise of local-first design.

When a coding agent produces a component or a prototype, that output is model-generated code. It could be well-structured, idiomatic HTML. It could also contain a script that reads your ~/.ssh/id_rsa and exfiltrates it. Both are possible outputs of a language model. The preview iframe is what Open Design intends to stand between those two cases — a documented design boundary, not an audited security guarantee.

As of v0.21.1 (verified September 2026), Open Design renders all artifact previews inside an <iframe sandbox="allow-scripts"> with no allow-same-origin permission. That single attribute omission is load-bearing: without allow-same-origin, the iframe's document is treated as having a unique, opaque origin. It cannot read cookies, cannot access localStorage, and cannot make requests back to the parent page. The agent's generated code runs in an isolated universe.

Open Design uses the HTML srcdoc attribute rather than a URL-based src. The artifact HTML is written directly into the iframe as a string. No server endpoint is needed to serve the content, and the sandbox attributes apply unconditionally.

Example
<!-- Standard HTML artifact preview -->
<iframe
  sandbox="allow-scripts allow-popups"
  srcdoc="<!DOCTYPE html><html>...artifact content...</html>"
></iframe>

<!-- JSX artifact preview (Babel bootstrap injected) -->
<iframe
  sandbox="allow-scripts"
  srcdoc="<html><head><script src="babel.min.js">...</script>...</html>"
></iframe>

If you encounter a fork or third-party build of Open Design that offers an "unsandboxed preview mode" for convenience, treat it as a security regression. Running model-generated code without the sandbox removes the primary designed barrier between a malicious or buggy generation and your local system. Treat the preview sandbox as a threat-model boundary by design rather than a cosmetic UX safeguard or a security guarantee.

Sandbox Attribute Constraints — OpenDesign v0.21.1, verified September 2026
Attribute present Effect Why Open Design uses / omits it
allow-scripts (present) Executes inline and bundled JavaScript Required for interactive prototypes, React/JSX runtime, and D3 charts
allow-same-origin (omitted) Would permit cookie and storage access Omitted; keeps iframe in a unique opaque origin with no ambient authority
allow-popups (conditional) Permits window.open() and link targets Added for static HTML artifacts that include navigation links
allow-forms (omitted) Would permit form submissions Omitted by default; form submissions in prototypes remain purely cosmetic

For JSX-based artifacts, the sandbox handles an additional constraint. Because the iframe has no external network access and no allow-same-origin, the JSX compilation must happen inside the iframe itself. The architecture injects a Babel standalone bootstrap so JSX compiles and React renders entirely within the sandboxed context, without making any external script requests.

The Electron desktop shell adds one more layer. The renderer process is sandboxed, and the daemon runs as a sidecar communicating via IPC. Generated code never runs directly in the Electron main process (the v0.9-era design also added HMAC-gated folder-import authentication). The bigger recent change is 0.21.0's live multi-file HTML previews: scripts, styles, images, modules, and relative requests keep working across navigation inside the preview, so a generated multi-page site behaves in the preview the way it will from disk. And since 0.20.2, preview state --- scroll position, live documents, in-progress edits --- survives switching files, tabs, and the Preview/Code toggle.

OpenDesign 0.21.1 workspace overview with the chat rail on the left, generated files and the live preview on the right, and the Preview/Code toggle in the toolbar
Figure 8.1 — The project workspace in OpenDesign v0.21.1. Chat and run history stay on the left; generated files and the live preview stay on the right, with Preview/Code as a single toggle. Screenshot from OpenDesign desktop v0.21.1 (September 2026).

Preview, Code, and Desktop toggles

The preview pane exposes three review modes without leaving the workspace. Preview renders the artifact inside the sandboxed iframe. Code shows the generated HTML source --- the handoff view for verifying token-driven output. Desktop widens the viewport for responsive checks. Switching tabs does not re-run generation; it only changes how the same on-disk files are presented.

OpenDesign 0.21.1 Code view showing generated HTML source with a DESIGN TOKENS block in a root CSS custom-property declaration
Figure 8.1a — The Code view. Readable source with a token block at the top --- the fastest audit for production-viable output. Screenshot from OpenDesign desktop v0.21.1 (September 2026).

Chat rail and NEXT STEP suggestions

The chat rail holds the full turn history, run cost, and mode chips. When a generation finishes, Open Design surfaces NEXT STEP suggestions derived from project state --- one-click follow-ups so you do not have to recall iteration syntax. The More menu expands the set when the first three shortcuts are not enough.

Open Design project workspace chat rail scrolled through prior turns with agent summary and follow-up prompt field
Figure 8.1b — The chat rail after a long run (captured at v0.15.1, July 2026). Prior turns, tool summaries, and the follow-up composer stay visible while you review the preview. By v0.21.1 the rail also groups a run's output under Files from this turn, offers Fork from here, and ends turns with next-step chips.
Open Design NEXT STEP suggestion chips with a More menu listing additional context-aware follow-up prompts
Figure 8.1c — NEXT STEP suggestions (captured at v0.15.1, July 2026). Context-aware shortcuts compress the iterate beat into a single click; More exposes the full set. The v0.21.1 rail pairs these with a TODOS checklist and per-turn file summaries.
My Take

The sandboxed preview is non-negotiable and should never be disabled, even though it occasionally causes preview-to-export divergence. I've run into cases where an artifact looks perfect in the preview and the exported HTML behaves differently because of how assets are resolved. That friction is real and worth acknowledging. But the alternative --- running model-generated code with full DOM access on my own machine --- is a risk I won't accept. The sandbox is the architecture's spine. If you're evaluating forks or derivatives of Open Design, the first thing to check is whether this constraint is preserved.

Agent writes artifact

Model generates HTML/JSX/CSS as files in .od/projects/

SSE stream to frontend

Daemon pushes write_file events over text/event-stream

srcdoc iframe

sandbox="allow-scripts", no allow-same-origin

Export pipeline

HTML / PDF / PPTX / MP4 / ZIP / MD

Figure 8.2 — The sandbox-in, files-out pipeline: generated code passes through an isolated iframe before the export pipeline serializes it into any of the six shippable formats.

8.2 Streaming the Artifact

SSE delivery and the streaming artifact parser

The preview doesn't appear after generation finishes. It appears while the agent is still writing. Understanding how that works explains both the responsiveness you see and the constraints it imposes on the export pipeline.

When you submit a prompt, the frontend sends a POST /api/chat request to the local daemon. The daemon responds immediately with a text/event-stream content type and begins pushing Server-Sent Events (SSE) back to the browser. Operating as a one-directional HTTP stream rather than a WebSocket connection, this approach avoids specialized protocol handshakes and bidirectional socket management.

The SSE stream carries two main event types during generation. text_delta events carry the agent's conversational output, which appears in the chat panel. tool_call events carry the agent's file operations, and the most important of these is write_file, which delivers the artifact's HTML content progressively as the agent writes it.

Output
# SSE stream from daemon (simplified)
# POST /api/chat -> text/event-stream

data: {"type":"text_delta","text":"Building a pricing page with three tiers..."}

data: {"type":"tool_call","tool":"write_file","args":{
  "path":"index.html",
  "content":"<!DOCTYPE html>\n<html>..."
}}

data: {"type":"text_delta","text":"The layout uses CSS Grid..."}

data: {"type":"done"}

The streaming artifact parser in the frontend receives these events and updates the srcdoc iframe in real time. As each write_file event arrives, the iframe's srcdoc attribute is rewritten with the new content. The result is the live-updating preview you see while generation runs: the page appears, then fills in, then finalizes.

This real-time update model has one important implication for the export pipeline. The export does not simply dump the final srcdoc value. The daemon holds the canonical artifact files in .od/projects/<id>/, and the export pipeline reads from those files rather than from the browser's iframe state. This is by design: the iframe state can diverge from the files if a streaming write is interrupted, so the files are the authoritative source.

SSE Event Types During Artifact Generation — OpenDesign v0.21.1, verified September 2026
Event type Payload Frontend action
text_delta Agent's conversational text fragment Appended to the chat panel
tool_call (write_file) Artifact file path and HTML content Written to .od/projects/<id>/; iframe srcdoc updated
done Empty Stream closed; preview settles; export buttons activate

Hot Reload

Once generation finishes, the preview continues to update if the artifact files change. The daemon watches the project directory for writes and pushes new write_file events over a persistent SSE connection. This means that if you manually edit an artifact file or if a second agent pass modifies it, the preview refreshes without any action on your part. The four-beat loop from Section 3.2 is hot-reloaded by default.

8.3 The Six Export Formats

Format matrix: what each produces and how

Open Design's export menu in v0.21.1 offers five entries --- PDF, PPTX, image, ZIP, and standalone HTML --- with MP4 produced by the HyperFrames render path rather than the menu. Earlier editions of this chapter counted Markdown as a sixth format; it does not appear in the current menu, and Chapter 03 already flags its status as unverified --- treat it the same way here. Each format is produced by a different mechanism, and each has a different relationship to the sandboxed preview. Knowing the mechanism is what lets you predict and prevent the divergence described in Section 8.6. One reliability note before the matrix: since 0.20.2, stuck exports finish in under sixty seconds and fail with a named reason instead of hanging --- "why is the export spinning" became an answer instead of a mood.

Export Format Matrix — OpenDesign v0.21.1, verified September 2026
Format Source artifact Produced by Use case
HTML (inlined) Any HTML artifact CSS inliner + asset URL rewriter to data: URIs Offline distribution; review without a server
PDF Any HTML artifact Puppeteer page.pdf() on rendered HTML Print-ready documents; formal handoffs
PPTX Deck artifacts Slide snapshot capture + pptxgenjs Presentations for stakeholders using PowerPoint/Keynote
MP4 HyperFrames motion artifacts Headless Chrome frame capture + FFmpeg encode Motion graphics; social content; video handoffs
ZIP Any artifact or project Daemon archive of project directory Full project portability; multi-file handoffs
Markdown Text and structured artifacts HTML-to-Markdown converter Not in the v0.21.1 export menu; verify availability in your build before relying on it

Every format except ZIP produces output from the artifact's rendered state. HTML inlining serializes the rendered DOM. PDF captures the Puppeteer-rendered page. PPTX captures slide snapshots. MP4 captures video frames. Only ZIP archives the raw source files. This distinction matters when external assets load in the preview but cannot be bundled --- ZIP is then the only format that preserves them faithfully.

Open Design project workspace showing an approved artifact export panel with HTML, PDF, PPTX, and ZIP selected
Figure 8.3 — The export panel appears on the same workspace surface as the prompt and preview. This run shows an approved artifact with HTML, PDF, PPTX, and ZIP selected, making the export model concrete instead of hiding it behind a generic download menu. Screenshot from Open Design v0.11.0, captured June 2026.

8.4 HTML and PDF

Inlined export and Puppeteer-generated PDF

HTML and PDF share an export strategy: both produce a single self-contained file from the artifact's rendered content. The difference is that HTML inlines assets while PDF captures a page render.

HTML Inlining

The HTML export pipeline reads the artifact's source HTML from .od/projects/<id>/, then runs an inliner that rewrites external references into the document itself. Every <link rel="stylesheet"> is replaced with an inline <style> block. Every <img src="..."> is replaced with a data: URI encoding the image in Base64. External scripts are inlined if they are local; remote scripts either stay as remote references or fail silently depending on the inliner's configuration.

Example
# Before export (in preview):
<link rel="stylesheet" href="/styles/main.css">
<img src="/assets/logo.png">

# After HTML inlining:
<style>
  /* all CSS from main.css inlined here */
</style>
<img src="data:image/png;base64,iVBORw0KGgo...">

The result is a single HTML file you can open offline, email to a stakeholder, or drop in a static host without any server-side dependencies. This is the format I use for design reviews: one file, no instructions. And since 0.19.2 the export is explicitly offline-safe: the inliner pulls project-local images, styles, fonts, modules, workers, and even nested documents into the single file, and the same path is available from the CLI as od export --format html. The stakeholder test got simpler --- if the exported file opens on a plane, it opens anywhere.

PDF Export

PDF export uses Puppeteer's headless Chromium to render the artifact HTML and call page.pdf(). The daemon launches a headless browser, navigates to the artifact, waits for the page to fully load including any fonts or deferred scripts, then triggers the PDF generation. The daemon uses Puppeteer as the documented PDF generation approach; the specific version is pinned as a daemon dependency and may lag behind the latest Puppeteer release.

Prompt
Export the current artifact to PDF, A4, with print margins.

PDF export is the format most likely to diverge from the preview. The preview renders in the sandboxed srcdoc iframe, which uses the browser's screen rendering model. Puppeteer renders in a headless Chromium instance using the print rendering model. Custom fonts loaded from the parent page don't transfer into Puppeteer's context unless they're bundled in the artifact. CSS that uses @media screen applies in the preview rather than the PDF output. This expected rendering divergence merits explicit pre-flight testing prior to any print-destined export.

1

Generate and preview your artifact until the preview looks correct in the sandbox.

2

Trigger the PDF export and open the resulting file locally, offline, before sharing it.

3

If font rendering or layout differs from the preview, check whether fonts are loaded via external URLs or self-contained. Switch to system fonts or embed font files in the artifact if print fidelity is required.

4

If page breaks are wrong, add explicit page-break-before or page-break-after CSS to the artifact and re-export.

8.5 PPTX, MP4, ZIP, and Markdown

The remaining four formats and their export strategies

PPTX, MP4, ZIP, and Markdown each serve a different downstream audience. Understanding how each is produced tells you when to reach for it and what to watch for.

PPTX: Deck Snapshots

PPTX export applies to deck artifacts generated by the deck skills. The history matters here. The original PPTX approach re-prompted the agent to regenerate each slide as PowerPoint-compatible content, which meant the export could diverge from the preview in layout and typography. That was replaced by a snapshot-based pipeline --- the daemon captures a rendered image of each slide from the preview and passes these images to pptxgenjs to assemble the file (merged in PR #3641 on June 2, 2026, resolving issue #1842) --- which made exports faithful but left the PPTX as image-per-slide. The current answer arrived in 0.20.0: editable PPTX fidelity. Imported Google Fonts travel into the file, authored line breaks are preserved instead of reflowed, layered backgrounds survive, and $-sequences land verbatim. The export is no longer a picture of your deck; it is your deck.

Fidelity is now high in both senses: slides look like the preview and they open as editable PowerPoint objects. The 0.20.0 fidelity work is what makes the PPTX row of every matrix in this chapter safe to recommend for PowerPoint-first stakeholders --- the "images, not text" caveat applies to pre-0.20.0 exports and to runs where the deck skill skipped slide structure, not to a current export of a well-formed deck.

When to use PPTX:

Stakeholder reviews where the audience's tool is PowerPoint or Keynote. Since 0.20.0 the export is editable --- fonts, line breaks, layered backgrounds, and $-sequences survive --- so a PowerPoint-first team can finish the deck in place.

When not to use PPTX:

Pre-0.20.0 exports, or runs where the deck skill fell back to the PDF-to-page path: those files are image-per-slide and cannot be text-edited. If slides arrive as pictures, re-run the deck generation so slide structure is emitted, then re-export.

MP4: HyperFrames Rendering

MP4 export is exclusive to HyperFrames motion artifacts. HyperFrames takes HTML and CSS animations, renders them frame by frame using a headless Chrome instance, and encodes the frame sequence into an MP4 file using FFmpeg. The bundled HyperFrames templates produce outputs at 1920×1080 at 30 fps (verified against the 23 pre-rendered template MP4s shipped in PR #3739, June 10, 2026), and since 0.20.0 the renderer runs from the packaged runtime pinned to the daemon rather than a system Chrome. Each bundled template's rendered preview file is under 1 MiB.

Render time scales with clip length and complexity. A 15-second intro animation renders significantly faster than a 60-second product demo. I have not measured average render time precisely across clip lengths, so budget conservatively: do not expect instant results. Keep clips short while iterating, and only render at full length for final export.

Prompt
Build a 15-second HyperFrames intro animation of a logo assembling from
grid lines, using the brand accent color. Render to MP4.

ZIP: Raw Project Archive

Output
# ZIP archive contents (typical single-artifact export):
project-abc123/
├── index.html          # main artifact
├── assets/
│   ├── logo.svg
│   └── hero.png
└── od-meta.json        # Open Design project metadata

ZIP export archives the project directory from .od/projects/<id>/. Unlike all other formats, ZIP preserves the source files without transformation. This makes it the correct choice when an artifact references external assets that cannot be inlined, when you want to hand off the raw files to another developer, or when you want a portable backup of everything the agent produced. The ZIP is also the only export format that survives cleanly if the artifact includes multiple interdependent files, such as a design system with separate CSS and component files.

Markdown: Text Artifact Export

Example
# HTML input (artifact section):
<h2>Features</h2>
<ul>
  <li>Local-first generation</li>
  <li>100+ design skills</li>
</ul>

# Markdown output:
## Features

- Local-first generation
- 100+ design skills

Markdown export applies to artifacts with significant text structure: documentation pages, content outlines, or structured HTML documents that were generated from a text-heavy skill. The pipeline runs an HTML-to-Markdown converter on the artifact. The resulting file is compatible with any Markdown-based CMS, static site generator, or Git-tracked documentation system. One honest caveat, carried over from Chapter 03: Markdown does not appear in the v0.21.1 export menu, so treat the mechanism described here as the documented pipeline and verify availability in your build before committing a workflow to it.

Markdown export loses layout. CSS positioning, column structures, and visual hierarchy do not translate into Markdown. If layout fidelity matters, use HTML export instead. Markdown export is for cases where the content is what you need and the styling is irrelevant to the downstream consumer.

Four Export Formats: When to Reach for Each — verified September 2026 (v0.21.1)
Format Best when Limitation
PPTX Deck review with PowerPoint audience; layout fidelity required Pre-0.20.0 exports are image-per-slide; current exports are editable --- verify older files before promising editability
MP4 Motion graphic is the final deliverable; social or video handoff Render time scales with clip length; not instant
ZIP Multi-file artifact; external assets; developer handoff; backup No transformation; downstream consumer must handle raw files
Markdown Text-heavy artifact for CMS or documentation; layout irrelevant Layout and visual hierarchy are lost in conversion

8.6 When Preview and Export Diverge

Gotchas, root causes, and fixes

Preview and export divergence is the most common frustration when working with the sandbox-in, files-out model. The preview renders in one context; the export pipeline renders in another. They usually agree. When they don't, the cause follows one of a handful of predictable patterns.

The root tension is architectural. The preview is a sandboxed iframe with the browser's font cache and network stack. Export formats use different renderers: Puppeteer for PDF, a snapshot capturer for PPTX, FFmpeg-mediated headless Chrome for MP4, and a static inliner for HTML. Each renderer has different capabilities. An asset that loads in the browser preview may not be reachable by Puppeteer, or may be blocked because the sandboxed iframe returns an opaque origin context that the inliner can't replicate.

Issues #2218 and #3744 (closed May–June 2026) documented this: the deck preview renders correctly from a raw URL, but the bridge transport that wraps the preview for export returns null, causing snapshot capture to fail silently. PR #2325 added fallback retry logic, but the pattern remains real: export capture can fail while the preview looks fine. Always verify the exported file alongside the preview.

Preview vs Export Divergence: Symptoms, Causes, and Fixes
Symptom Cause Fix
Fonts render correctly in preview but use fallback fonts in PDF External font URLs (e.g., Google Fonts) are not fetched by Puppeteer in the export context Inline the font via @font-face with data: URI or use system fonts for PDF-destined artifacts
Images appear in preview but are blank or broken in HTML export Image sources are external URLs that the HTML inliner cannot reach or embed Bundle images locally in the artifact before export, or verify the inliner config allows fetching external assets
PPTX export produces blank slides or fails silently Preview snapshot capture returns null; bridge transport between the srcdoc iframe and the export pipeline fails Reload the preview until the artifact fully renders, then re-trigger export; if persistent, check the daemon logs for bridge transport errors
Layout differs between preview and PDF (column breaks, grid gaps) Puppeteer uses print rendering model; @media screen CSS does not apply Add explicit @media print styles to the artifact, or accept the difference and use HTML export for screen-fidelity review

External assets that load in the preview can break in the inlined HTML export. The preview iframe fetches resources with the browser's full network access; the HTML inliner runs in the daemon and may not reach the same CDN-hosted fonts or authenticated endpoints. Verify exported files offline before sending --- open the exported HTML with the network tab active and look for failed asset requests. This applies especially to artifacts that load external fonts or image CDNs.

The Verification Habit

Sandbox in, files out --- this is the model that works cleanly for the majority of artifacts. Divergence clusters around external assets and format-specific rendering. Build a short verification step into your export workflow: trigger the export, open the file independently of the preview, and confirm they match. For HTML, do this offline. For PDF, check font rendering. For PPTX, scroll all slides in a presentation tool. Two minutes of verification prevents "it looked right in the preview" mistakes from reaching a stakeholder.

My Take

Preview/export divergence stems naturally from pairing an isolated security sandbox with diverse export renderers. Because each export format relies on its own rendering context, output cannot always duplicate the browser sandbox exactly. Preserving security requires keeping the sandbox intact while systematically auditing every export before distribution. Checking every exported file pays off: skipping that verification once produced a client-delivered PDF with a blank first page caused by an unbundled web font.

8.7 Versions, Provenance, and Design Jury

Per-file version history with originating prompts, recycle-to-template, and five-panel adjudication

Artifacts can transition beyond the sandbox through direct exports, version checkpoints, or structured Design Jury reviews so you can restore, recycle, or refuse a generation before it ships.

Versions carry the prompt that made them

Every meaningful file write creates a version entry that stores the originating prompt --- a spine in place since the v0.15.1 captures and current in v0.21.1. The Versions panel lists those entries per file ("Version history · N versions") with a Current badge, timestamps, a prompt excerpt, and an AI-edit tag, revealing the rationale behind each revision alongside its timestamp. Restore returns the file; Download pulls that exact version to disk; the chat history still explains how you got there.

OpenDesign 0.21.1 Versions panel listing per-file version cards with Current and AI edit badges, a prompt excerpt, and Switch to this version and Download actions
Figure 8.4 — The Versions panel in v0.21.1. Each entry discloses the prompt that produced it; Switch to this version and Download are first-class actions, so a version-pinned export is one click, not a git ritual. Screenshot from OpenDesign desktop v0.21.1 (September 2026).

Export menu and Save as template

The toolbar's Export menu in v0.21.1 reads: Export as PDF, Export as PPTX, Export as image, Download as .zip, and Export as standalone HTML --- with a Save group that includes Save as template…. Ship formats and recycle sit in one menu, so a good run becomes tomorrow's starting point --- the same closed loop as crystallising a successful run into a skill via Automations.

OpenDesign 0.21.1 Export menu showing Export as PDF, Export as PPTX, Export as image, Download as .zip, Export as standalone HTML, and Save as template
Figure 8.5 — The v0.21.1 Export menu: PDF, PPTX, image, .zip, and standalone HTML beside Save as template. Screenshot from OpenDesign desktop v0.21.1 (September 2026).

Design Jury — adjudication as a feature

Design Jury (also described in product copy as a Critique Theater) is a Settings toggle --- in v0.21.1 it lives in the General section, described as a five-panel review that scores the output before shipping. When enabled, the scored review appears alongside agent generations. You can interrupt at any time. It provides a structured automated check to supplement human taste before treating a Heavy Design run as shippable.

OpenDesign 0.21.1 Settings General page showing the Design Jury toggle among system preferences
Figure 8.6 — Design Jury in Settings → General (v0.21.1). Enable to stream a five-panel review beside generation; the preference persists across restarts. Screenshot from OpenDesign desktop v0.21.1 (September 2026).

Pair Jury with Plan mode on high-stakes work: Plan locks the brief, Design builds, Jury scores, then you export. That sequence is slower than a single Heavy send --- and usually cheaper than three unplanned Design retries.

8.8 Export, Share, and Handoff as Direct Actions

Three header actions, three delivery jobs

For a few releases, Export, Share, and Handoff lived inside a single tabbed popover in the workspace header --- one door for three jobs. v0.19.0 (August 11, 2026) splits them back into three direct header actions (as of August 2026). Export leads as file delivery: the six formats from section 8.3, straight to disk. Share covers links and publishing. Handoff returns to its split button, so the developer-facing bundle is one click instead of a tab hunt.

Two quiet fixes shipped with the split. The HTML and React component viewers now share structure, so what you inspect in one matches the other. And an off-contract editor response no longer crashes the viewer --- a malformed reply degrades into an error state you can dismiss instead of a white screen that eats the session.

What changed most in daily work is what "export" now means visually. Exports follow the composed preview: image exports respect the active preview viewport, so the PNG you get is the frame you were actually looking at, while framework decks are captured at their authored size no matter how you've resized the pane. If the preview shows a cropped mobile viewport, the image export shows the same crop --- confirm the viewport prior to triggering Export. The Files from this turn summary now counts unique files, so a run that revises index.html three times reports a single file rather than three duplicates.

The model underneath hasn't moved. The artifact is still generated inside the sandbox and still leaves as files --- sandbox in, files out. The split only removes a layer of UI between you and that exit. And because v0.19.1 auto-opens new image and video outputs in the preview, the loop from generation to export is shorter than it has ever been: generate, glance, ship.

Worth spelling out, because the labels are the documentation. The Share menu has three groups: QUICK SHARE · OPENDESIGN with a single Get a share link action; SHARE ON YOUR OWN HOSTING with Deploy to Vercel and Deploy to Cloudflare Pages --- deployment targets that distinguish preview from production (0.16.0) --- and SAVE with Save as template…. The hosted-link path and the your-own-hosting path sit side by side, which is the no-lock-in argument rendered as a menu.

Handoff is the developer exit. The menu has two tabs --- Open with editor and Copy for CLI --- plus Copy path. The editor list shows what is installed on your machine (in my case Cursor, VS Code, Windsurf, Antigravity, Xcode, Finder, Terminal, and Warp; Zed appears greyed until installed), Cursor gets a direct Open in Cursor button, and Copy for CLI hands you the invocation your terminal agent needs. Design on the canvas, code in the editor, one menu between them.

OpenDesign 0.21.1 Share menu with QUICK SHARE · OPENDESIGN, Deploy to Vercel, Deploy to Cloudflare Pages, and Save as template
Figure 8.7 — The Share menu in v0.21.1: a hosted quick-share link, self-hosting deploys to Vercel or Cloudflare Pages with preview versus production targets, and template save on one surface. Screenshot from OpenDesign desktop v0.21.1 (September 2026).
OpenDesign 0.21.1 Handoff menu with Open with editor and Copy for CLI tabs listing installed editors including Cursor, VS Code, Windsurf, Antigravity, Xcode, Finder, Terminal, and Warp
Figure 8.8 — The Handoff menu: open the project in an installed editor or copy a CLI-ready invocation. Screenshot from OpenDesign desktop v0.21.1 (September 2026).
My Take

The popover was the classic "one door for three jobs" mistake, and the split finally matches how people actually deliver. Nobody exports, shares, and hands off in the same motion --- you pick one, per audience, per moment. I've deleted the "click the export icon, then the second tab" line from my team runbook, and new hires find Handoff without being shown. When a UI change deletes a line from your onboarding doc, the change is working.

Next Chapter

The Plugin Ecosystem

Expert suites, Skills, Figma migration, and code-refresh-to-brand

Continue Reading

©2026 Mehran Mozaffari. Free for personal/noncommercial use (CC BY-NC-ND 4.0); commercial license required for business use.