The agent-native graphic design framework. Design graphics as React components, click any object on the canvas to nudge or restyle it (the edit lands in your source), and export to PNG / SVG / PDF. The canvas analog of open-slide and open-doc — same portable spine, a new artifact model.
discover files → virtual module → React component contract → click-to-source editing → export
(Vite glob) (loadDesign) (export default Scene[]) (loc-tags + fiber) (png/svg/pdf)
Requires Node ≥ 20.19 (or ≥ 22.12) — the version Vite 7 needs.
Start a new project — nothing to clone; this scaffolds a project and pulls @opencanva/core from npm:
npm create opencanva@latest my-designs
cd my-designs
npm install
npm run dev # → http://localhost:5173You get a ready-to-run project: a starter design under designs/, opencanva.config.ts, and AGENTS.md + skill folders so any AI agent (Claude Code, Codex, Cursor, …) can author for you out of the box.
Or explore / contribute to the framework itself:
git clone https://github.com/daniellee-ux/open-canva
cd open-canva && npm install && npm run devOpen a design at /d/<id>. Toggle Edit to select objects, drag to move, grab handles to resize/rotate, recolor, or leave a comment for your agent. Hit Export for PNG / SVG / PDF.
A design lives in designs/<id>/index.tsx and default-exports an array of Scenes (artboards). Each Scene places graphic objects at absolute pixel coordinates:
import { Box, Text, Ellipse, type Scene, type Artboard, type DesignMeta } from '@opencanva/core';
const Poster: Scene = () => (
<>
<Ellipse x={700} y={-120} w={500} h={500} fill="var(--ox-accent)" opacity={0.3} />
<Text x={80} y={120} w={900} size={160} weight={800} font="display">Big headline</Text>
<Box x={80} y={820} w={360} h={120} fill="var(--ox-accent)" radius={60}>
<Text x={0} y={0} w={360} h={120} align="center" valign="center" size={44} weight={700} color="#fff">
Shop now →
</Text>
</Box>
</>
);
Poster.id = 'poster';
export const artboard: Artboard = { w: 1080, h: 1080 };
export const meta: DesignMeta = { title: 'My poster', theme: 'sunset', createdAt: '2026-06-20T12:00:00Z' };
export default [Poster] satisfies Scene[];export defaultisScene[]— one component per artboard (most designs have one; several = a carousel / size set). Multiple boards flow in a row by default;export const layout({ wrap: 3 },{ direction: 'column' }) or a scene'sbreakarranges them as a grid or a vertical stack.- Objects:
<Box>,<Text>,<Ellipse>,<Line>,<ImageObject>,<Group>,<Icon>,<Illustration>— positioned withx/y/w/h, rotated withrotate, themed withvar(--ox-*)tokens. - Themes:
ember,noir,sunset,mint,blueprint,bubblegum(see/themes), or roll your ownDesignSystem.
- Click-to-source. Every object you click resolves to the exact
<Box>/<Text>in your source (via injecteddata-ox-locread off the React fiber — works across files and components). Drag/resize/recolor rewrite the object's props in place through a dev-only write-back API; the source stays byte-stable so HMR is surgical. - Comments → edits. Leave a
@canva-commenton any object; the bundledapply-commentsskill applies them. - Current-design pointer. The dev server writes
.opencanva/current.jsonso an agent can resolve "this design / the object I selected". - Marketing message → image → cover → design. The bundled
write-marketing-copyskill creates a truthful click/read/share content package;select-marketing-imagechooses, ranks, and crops the focal image;design-marketing-coverturns both into a thumbnail-tested composition.create-designorchestrates the pipeline when the graphic has a marketing goal. - Works with any agent. A root
AGENTS.md(the cross-tool standard read by Codex, Cursor, Copilot, …) carries the repo guide, andCLAUDE.mdis a byte-identical copy of it (kept in sync by CI). The nine authoring skills —canva-authoring,create-design,write-marketing-copy,select-marketing-image,design-marketing-cover,apply-comments,current-design,create-theme,svg-illustration— ship as Agent Skills:npm run synccopies them into both.agents/skills/(vendor-neutral, committed) and.claude/skills/(local).opencanva initscaffolds a new project with all of it baked in.
packages/core @opencanva/core — runtime, Vite plugin, CLI, primitives, skills, project template
apps/demo demo workspace — ships the start-here starter; your own designs stay local
opencanva <dev|build|preview|sync|init> runs the TypeScript CLI directly via tsx — no build step.