Dong Tan Nguyen
Case study 03

crafted-design/editor

A portable design-document system for React, where people and agents can author the same page while the host keeps control of how it looks and runs.

Years2026
ScopeOpen-source React library
48 components, 3 adapters

What it had to do

Most visual builders entangle three decisions that ought to stay separate: the page a person composes, the design system that renders it, and the editing machinery that makes it draggable. That makes a change of UI kit feel like a content migration, and makes the resulting pages difficult to use outside the editor.

I wanted one document that could be composed by a person, changed by an agent, rendered in a product, or emitted as static HTML. The host application should retain ownership of its theme, components, data, storage, and controls; the document should stay portable through all of it.

React 19TypeScriptTailwind v4Craft.jsMCPSemVer SDK
canonical components
48
built-in rendering adapters
3
document model, every surface
1
The shape of it
host-owned seamsportable document path
Guided view 0 / 3Ready

Explore the system

Step through the three authored paths.

[ ] chapters · P play · Esc reset
mounts Editoredit actionsserializepersistregistrationscomponent defsactive implclasses + tokensMCP clienttool callsbuild + validatedisplayPublic SDK · frozen SemVer surfacePublic SDKfrozen SemVer surfaceCanonical Registry · 48 components · Zod propsCanonical Registry48 components · Zod propsAdapter Layer · shadcn · MUI · plain HTMLAdapter Layershadcn · MUI · plain HTMLStyle + Theme Layer · breakpoints · states · tokensStyle + Theme Layerbreakpoints · states · tokensHost React App · React + Craft.js peersHost React AppReact + Craft.js peersEditor UI · toolbox · inspector · canvasEditor UItoolbox · inspector · canvasCraft.js Bridge · CanonicalNode + resolverCraft.js BridgeCanonicalNode + resolverDocument JSON · Zod envelope · adapter-freeDocument JSONZod envelope · adapter-freeStorage Adapter · IndexedDB → localStorageStorage AdapterIndexedDB → localStorageAI Coding Agent · agent tool clientAI Coding Agentagent tool clientMCP Server · tool interfaceMCP Servertool interfaceHeadless API · no browser · no CraftHeadless APIno browser · no CraftDocumentRenderer · no chrome · lightweightDocumentRendererno chrome · lightweight

The editor, runtime renderer, and headless tools all meet at the same canonical document. A host chooses its component adapter, theme, storage, and extensions without asking existing documents to migrate with it.

One event, end to end

How it moves

  1. 01

    Compose

    A person works in the visual editor, or an agent inspects the same component schemas and builds the same node tree through a tool interface.

  2. 02

    Describe

    The page becomes a canonical JSON document: component identities, props, hierarchy, slots, and the metadata needed to keep the tree understandable.

  3. 03

    Adapt

    A rendering adapter maps canonical components to the host's chosen implementation, so visual language can change without rewriting the document.

  4. 04

    Render

    The same document can appear in the editor, a production React renderer, or a headless/static HTML path without bringing the editor along.

  5. 05

    Verify

    Tooling can validate the document, render a real result, and check visual constraints before an agent hands the exact same JSON back to a person.

  6. 06

    Persist & evolve

    The host owns where documents live, while versioned persistence and migrations give saved work a deliberate path forward.

Designed to outlive a UI kit

The document is the contract

Compose once. Render anywhere. Verify before handoff.

  • The design system changes

    Canonical component identities stay stable while an adapter changes how they render, keeping a UI-library decision out of the saved page tree.

  • An agent makes an edit

    Schemas and document validation make the change inspectable; rendering and visual checks let it be assessed as a page rather than trusted as text output.

  • Production needs no editor

    Runtime and headless paths consume the document directly, so an application can ship the result without coupling its visitor experience to authoring controls.

What I actually did

  • Designed the canonical seam

    Defined a library of canonical components with portable props, slots, and defaults, so a document describes intent rather than leaking the implementation details of one UI kit.

  • Made adapters genuinely swappable

    Separated the registry from its rendering adapters and shipped built-in paths for different component systems. A host can select its visual language while preserving the same document and editor workflow.

  • Separated authoring from delivery

    Built distinct editor, renderer, and headless entry points so composing a page, rendering it in a product, and producing static output are related capabilities—not one oversized runtime.

  • Made AI output inspectable

    Added an MCP surface that lets an agent discover schemas, build or mutate a document, render the actual result, check visual constraints, and return ordinary document JSON for a human to review.

  • Treated it as a library people can depend on

    Designed the public SDK, persistence boundaries, migrations, and versioned package surface around the fact that a visual-builder document is somebody else's durable content—not an internal implementation detail.

The contribution trail

What changed because I was there

This is an open-source project. The diagram describes its public architecture at a useful level and deliberately leaves package internals out of the page.

  • 01

    A portable page model

    Established canonical JSON as the shared contract between the editor, agents, renderers, and persistence instead of allowing each surface to invent its own representation.

  • 02

    Design-system choice stays host-owned

    Created the adapter boundary that lets a product bring its own components and theme while keeping authoring behavior and saved documents consistent.

  • 03

    Humans and agents share one workflow

    Made the tool-assisted path produce the exact kind of document the editor uses, so AI changes can be rendered, validated, and opened by a person without translation.

  • 04

    Editor-free delivery paths

    Provided production and headless rendering routes that preserve the document model while allowing hosts to choose the lightest runtime for their use case.

  • 05

    A durable integration surface

    Made extension, persistence, and migration concerns explicit so consumers have a supported way to carry their own components and saved documents forward.