open-canvas
Charts, tables, and structured visuals agents can one-shot — from a single .canvas.tsx file to HTML, PNG, PDF, JPG, or an IDE-ready canvas. Same cursor/canvas primitives as Cursor Canvas; no Cursor app required to build or export.
Web rendering uses the Mantine shim: cursor-canvas-web (@flesler/cursor-canvas-web on npm).
Install
npm install -g @flesler/open-canvas
PNG, PDF, and JPG use headless Chromium (installed on first generate).
Agent skill
open-canvas skill ~/.cursor/skills/open-canvas # SKILL.md only — read after open-canvas is on PATH
Installs agent guidance for authoring and exporting .canvas.tsx files with open-canvas.
Author a .canvas.tsx
One React file: charts, tables, callouts, forms — import only from cursor/canvas. Static data can live in sibling ./data/* files. Saved toggles and form state can live in <stem>.canvas.data.json beside the canvas (same keys as useCanvasState).
import { Stack, H1, BarChart } from "cursor/canvas";
import report from "./data/report.json";
Some components accept an extra prop with features beyond the Cursor SDK, such as <BarChart extra={{ valueAxis: { scale: "log" } }} />. Cursor ignores extra, so the canvas still renders there. See the shim's superset docs.
Generate
open-canvas generate path/to/report.canvas.tsx
open-canvas verify path/to/report.canvas.tsx
| Command | Purpose |
|---|---|
generate <canvas> | HTML, PNG, PDF (default) into ./out |
verify <canvas> | Typecheck cursor/canvas and data imports |
skill [dir] | Print or install agent SKILL.md |
vendor-path | Print bundled cursor/canvas reference and SDK types |
| Flag | Default |
|---|---|
-o, --out | ./out beside the canvas |
-t, --theme | light or dark |
-f, --formats | html,png,pdf — also jpg, cursor |
-n, --name | Output basename (default: canvas stem) |
-w, --width | Playwright viewport width (default 1280) |
--min-height | Optional minimum page height in px |
--selector | Export only matched sections |
--inline-state | With cursor: embed .canvas.data.json in the emitted file |
-q, --quiet | No stdout on success (outputs at {--out}/{--name or stem}.{ext}) |
Exports read .canvas.data.json when present. Run a separate generate for the IDE file: open-canvas generate path/to/x.canvas.tsx --formats cursor (optionally -o / -n for {dir}/{stem}.canvas.tsx). --formats cursor inlines ./data/*; add --inline-state to include saved UI state too.
Theme in canvas code: useHostTheme() — same hook and return value in Cursor and in export. Use generate --theme / --brand when you need a fixed light/dark or Cursor/Grok look in png/html/pdf.
License
MIT — LICENSE.