Most components in Misaki Studio are a tree of nodes you draw. A code component is the other kind: the same component, authored as React source instead.
It exists for the cases a canvas is the wrong tool for — a third-party chart or map library, a hand-tuned <canvas> widget, a piece of imperative logic that would be tortured as wires. Misaki Studio lets that one component drop to code and keeps everything else about it the same.
Its path. A component file under components/code/ is a code component; that is how the kind is decided, the same way a file under pages/ is a page. The file holds a single code node containing the React source.
Everything else about it is unchanged: it declares properties and states like any other component, it appears in the file tree, and its instances are placed inside other designs in the usual way. A caller cannot tell the difference.
Working with an AI agent,
create-code-componentmakes one directly andupdate-code-componentreplaces its source. See Connect to MCP.
The source must default-export a React function component:
export default function (props) {
return <div>…</div>;
}Read the shape of props carefully. Everything you declared on the component arrives in one object per feature, not spread across the top level:
props.properties.label — a declared property — not props.label.
props.states, props.setState, props.getState — the component's states.
props.contents — mounted CMS content.
props.apis — mounted API loaders.
props.storages — mounted storage.
props.validator — the component's validator.
props.timelines — its timelines.
props.children — its children slots.
props.properties.label rather than props.label is the mistake to expect the first time. The shape is identical in the canvas preview and in exported code, so anything that works in one works in the other.
Replace the source in place. The file keeps its uuid, its declared properties and states, and every instance already placed on a page. Deleting and recreating the component throws all three away and leaves you re-placing instances by hand.
Like any other component, plus its source:
name.tsx — the generated wrapper, same as any component.
name.module.scss — its styles.
the transpiled source — your React source, compiled to ESM JavaScript.
So a code component is not a special case downstream — it lands in the export next to everything else and imports the same way.
They run real JavaScript. That has a practical consequence when something misbehaves: a code component can be stopped at a genuine breakpoint, stepped and inspected, because there is actual JS to break on.
Node-tree logic has none — it is data, played by the interpreter — so it is inspected a different way, by stepping the interpreter rather than the JavaScript. See Debug a component.
A code component opts out of everything the canvas gives you for free: the style panel, variants, responsive screens, timelines, and design-system tokens binding themselves to what you drew. You get a blank file and full control, and you own the consequences.
Reach for it when the canvas genuinely cannot express the thing. For everything else, the drawn component is the one that stays editable by whoever comes next — including a designer who does not read React.
Components — variants, properties and slots, for the drawn kind.
How export works — what the generated code looks like.