2026-02-28 05:12:18 +00:00
# OpenPencil
Initial commit: Tauri + CanvasKit + React editor scaffold
- Tauri v2 desktop shell with 1280x800 window
- CanvasKit WASM (Skia) rendering via WebGL2
- Scene graph with typed nodes (Frame, Rectangle, Ellipse, Line, etc.)
- Skia renderer with fills, strokes, rounded corners, opacity, rotation
- Selection system with resize handles
- Undo/redo manager (inverse command pattern with batching)
- Bottom toolbar (Select, Frame, Rect, Ellipse, Line) matching Figma UI3
- Left layers panel, right properties panel
- Pan (scroll), zoom (Ctrl+scroll toward cursor)
- Keyboard shortcuts: V/F/R/O/L for tools, Cmd+Z undo, Backspace delete
- 5 demo shapes rendered on canvas
2026-02-27 12:48:29 +00:00
2026-03-28 12:42:21 +00:00
Open-source design editor. Opens `.fig` and `.pen` design files, includes built-in AI, and ships as a programmable toolkit with a headless Vue SDK for building custom editors.
Initial commit: Tauri + CanvasKit + React editor scaffold
- Tauri v2 desktop shell with 1280x800 window
- CanvasKit WASM (Skia) rendering via WebGL2
- Scene graph with typed nodes (Frame, Rectangle, Ellipse, Line, etc.)
- Skia renderer with fills, strokes, rounded corners, opacity, rotation
- Selection system with resize handles
- Undo/redo manager (inverse command pattern with batching)
- Bottom toolbar (Select, Frame, Rect, Ellipse, Line) matching Figma UI3
- Left layers panel, right properties panel
- Pan (scroll), zoom (Ctrl+scroll toward cursor)
- Keyboard shortcuts: V/F/R/O/L for tools, Cmd+Z undo, Backspace delete
- 5 demo shapes rendered on canvas
2026-02-27 12:48:29 +00:00
2026-02-28 05:12:18 +00:00
> **Status:** Active development. Not ready for production use.
2026-03-28 12:42:21 +00:00
>
2026-03-28 12:46:49 +00:00
> **Note:** There is another open-source project with the same name — [OpenPencil by ZSeven-W](https://github.com/ZSeven-W/openpencil), focused on AI-native design-to-code workflows. This project focuses on Figma-compatible visual design with real-time collaboration.
Initial commit: Tauri + CanvasKit + React editor scaffold
- Tauri v2 desktop shell with 1280x800 window
- CanvasKit WASM (Skia) rendering via WebGL2
- Scene graph with typed nodes (Frame, Rectangle, Ellipse, Line, etc.)
- Skia renderer with fills, strokes, rounded corners, opacity, rotation
- Selection system with resize handles
- Undo/redo manager (inverse command pattern with batching)
- Bottom toolbar (Select, Frame, Rect, Ellipse, Line) matching Figma UI3
- Left layers panel, right properties panel
- Pan (scroll), zoom (Ctrl+scroll toward cursor)
- Keyboard shortcuts: V/F/R/O/L for tools, Cmd+Z undo, Backspace delete
- 5 demo shapes rendered on canvas
2026-02-27 12:48:29 +00:00
2026-03-06 17:54:48 +00:00
**[Try it online →](https://app.openpencil.dev/demo)** · [Download ](https://github.com/open-pencil/open-pencil/releases/latest ) · [Documentation ](https://openpencil.dev )
2026-03-01 13:03:25 +00:00
2026-03-01 12:57:01 +00:00

2026-02-28 20:36:55 +00:00
2026-03-08 07:47:42 +00:00
## Installation
**macOS (Homebrew):**
```sh
brew install open-pencil/tap/open-pencil
```
Or download from the [releases page ](https://github.com/open-pencil/open-pencil/releases/latest ), or [use the web app ](https://app.openpencil.dev ) — no install needed.
2026-03-08 07:46:38 +00:00
## What it does
2026-02-28 05:12:18 +00:00
2026-03-28 12:42:21 +00:00
- **Opens `.fig` and `.pen` files** — read and write native Figma files, open Pencil documents, copy & paste nodes between apps
- **AI builds designs** — describe what you want in chat, 90+ tools create and modify nodes. Connect OpenRouter, Anthropic, OpenAI, Google AI, Z.ai, MiniMax, or compatible endpoints
2026-03-08 07:46:38 +00:00
- **Fully programmable** — headless CLI, Figma Plugin API via `eval` , MCP server for AI agents
2026-03-28 12:42:21 +00:00
- **Vue SDK for custom editors** — headless components and composables for embedding OpenPencil into other apps or building workflow-specific editing surfaces. [Read the SDK docs → ](https://openpencil.dev/programmable/sdk/ )
2026-03-08 07:46:38 +00:00
- **Real-time collaboration** — P2P via WebRTC, no server, no account. Cursors, presence, follow mode
2026-03-08 15:29:44 +00:00
- **Auto layout & CSS Grid** — flex and grid layout via Yoga WASM, with gap, padding, alignment, track sizing
2026-03-08 07:46:38 +00:00
- **Tailwind CSS export** — export any selection as HTML with Tailwind v4 utility classes
- **~7 MB desktop app** — Tauri v2 for macOS, Windows, Linux. Also runs in the browser as a PWA
P2P collaboration: cursors, follow mode, cleanup
- Broadcast cursor position from canvas mouse move via awareness
- Broadcast selection changes via reactive watcher on selectedIds
- Follow mode: click peer avatar to track their viewport (pan + zoom)
- Zoom broadcast via watcher on store.state.zoom, not just mouse move
- Figma-style cursor arrows: colored fill, white border, name pill
- Stale cursor cleanup: removeAwarenessStates on peer leave
- MQTT signaling (replace Nostr), STUN + TURN ICE servers
- Collab constants extracted to src/constants.ts
- crypto.getRandomValues() replaces Math.random() everywhere
- Provide/inject for collab composable (COLLAB_KEY)
- Update README (collab section, tech stack), CHANGELOG, AGENTS.md
- AGENTS.md: release process, CI workflows, documentation guidelines
2026-03-01 15:11:07 +00:00
2026-02-28 22:28:24 +00:00
## CLI
2026-03-08 06:50:01 +00:00
```sh
bun add -g @open -pencil/cli
```
2026-03-28 12:42:21 +00:00
### Inspect design files
2026-03-08 06:50:01 +00:00
Browse node trees, search by name or type, dig into properties — all without opening the editor:
```sh
open-pencil tree design.fig
2026-03-28 12:42:21 +00:00
open-pencil find design.pen --type TEXT
2026-03-08 06:50:01 +00:00
open-pencil node design.fig --id 1:23
open-pencil info design.fig
```
```
[0] [page] "Getting started" (0:46566)
[0] [section] "" (0:46567)
[0] [frame] "Body" (0:46568)
[0] [frame] "Introduction" (0:46569)
[0] [frame] "Introduction Card" (0:46570)
[0] [frame] "Guidance" (0:46571)
```
XPath query for node selection (#82)
* Add XPath query for node selection
- packages/core/src/xpath.ts: XPath engine using fontoxpath with custom
DOM facade over SceneGraph nodes
- RPC command: 'query' with selector, page, limit params
- CLI command: 'open-pencil query <file> <xpath>' with --json, --page, --limit
- AI/MCP tool: 'query_nodes' with XPath examples in description
- Queryable attributes: name, width, height, x, y, visible, opacity,
cornerRadius, fontSize, fontFamily, fontWeight, layoutMode, itemSpacing,
padding*, strokeWeight, rotation, locked, blendMode, text, lineHeight,
letterSpacing
* Add tests and docs for XPath query
- 9 unit tests for queryByXPath/matchByXPath core functions
- 6 tool tests for query_nodes AI/MCP tool
- README: query examples in CLI section
- VitePress docs: patterns, queryable attributes, example output
- CHANGELOG: feature entry
* Lazy-load fontoxpath to avoid bundling in desktop app
- Dynamic import() instead of static import for fontoxpath
- queryByXPath/matchByXPath now async (they were sync before)
- RpcCommand.execute allows R | Promise<R> for async commands
- Fix 2 lint errors (unnecessary optional chain, always-truthy)
- Update all tests and CLI to await results
2026-03-09 12:32:27 +00:00
### Query with XPath
Use XPath selectors to find nodes by type, attributes, and structure:
```sh
open-pencil query design.fig "//FRAME" # All frames
open-pencil query design.fig "//FRAME[@width < 300 ] " # Frames under 300px
open-pencil query design.fig "//TEXT[contains(@name, 'Button')]" # Text with 'Button' in name
open-pencil query design.fig "//*[@cornerRadius > 0]" # Rounded corners
open-pencil query design.fig "//SECTION//TEXT" # Text inside sections
```
2026-03-08 06:50:01 +00:00
### Export
2026-03-28 12:42:21 +00:00
Render to PNG, JPG, WEBP, SVG, `.fig` , or JSX — or export selections/pages as `.fig` and convert whole documents between supported formats:
2026-03-08 06:50:01 +00:00
```sh
2026-03-28 12:42:21 +00:00
open-pencil export design.fig # PNG
open-pencil export design.fig -f jpg -s 2 -q 90 # JPG at 2x, quality 90
open-pencil export design.fig -f fig --page "Page 1" # Export a page as .fig
open-pencil export design.fig -f jsx --style tailwind # Tailwind JSX
open-pencil convert design.pen output.fig # Convert between document formats
2026-03-08 06:50:01 +00:00
```
```html
< div className = "flex flex-col gap-4 p-6 bg-white rounded-xl" >
< p className = "text-2xl font-bold text-[#1D1B20]" > Card Title< / p >
< p className = "text-sm text-[#49454F]" > Description text< / p >
< / div >
```
### Analyze design tokens
Audit an entire design system from the terminal — find inconsistencies, extract the real palette, spot components waiting to be extracted:
```sh
open-pencil analyze colors design.fig
open-pencil analyze typography design.fig
open-pencil analyze spacing design.fig
open-pencil analyze clusters design.fig
```
```
#1d1b20 ██████████████████████████████ 17155×
#49454f ██████████████████████████████ 9814×
#ffffff ██████████████████████████████ 8620×
#6750a4 ██████████████████████████████ 3967×
3771× frame "container" (100% match)
size: 40× 40, structure: Frame > [Frame]
2982× instance "Checkboxes" (100% match)
size: 48× 48, structure: Instance > [Frame]
```
### Script with Figma Plugin API
`eval` gives you the full Figma Plugin API. Modify the file, write it back:
```sh
open-pencil eval design.fig -c "figma.currentPage.children.length"
open-pencil eval design.fig -c "figma.currentPage.selection.forEach(n => n.opacity = 0.5)" -w
```
### Control the running app
When the desktop app is running, omit the file argument — the CLI connects via RPC and operates on the live canvas. Useful for automation scripts, CI pipelines, or AI agents that need to interact with the editor:
2026-02-28 22:28:24 +00:00
```sh
2026-03-08 06:50:01 +00:00
open-pencil tree # Inspect the live document
open-pencil export -f png # Screenshot the current canvas
open-pencil eval -c "figma.currentPage.name" # Query the editor
2026-02-28 22:28:24 +00:00
```
All commands support `--json` for machine-readable output.
2026-03-08 07:46:38 +00:00
## AI & MCP
### Built-in chat
2026-03-28 12:42:21 +00:00
Press < kbd > ⌘< / kbd > < kbd > J< / kbd > to open the AI assistant. It has 90+ tools that can create shapes, set fills and strokes, manage auto-layout, work with components and variables, run boolean operations, analyze design tokens, and export assets. Bring your own API key for OpenRouter, Anthropic, OpenAI, Google AI, Z.ai, MiniMax, or compatible endpoints. No backend, no account.
2026-03-02 10:57:03 +00:00
Harden ACP transport, MCP server, and add permission dialog
- Extract mapUpdate to testable module, dynamic import for @tauri-apps/plugin-shell
- Add warnings for unhandled ACP content types and empty tool titles
- MCP server: session limit (max 10), fix null WS comparison, guard JSX preprocessing
- MCP server: read version from package.json instead of hardcoded 0.0.0
- MCP tests: use port 0 (OS-assigned) to prevent collision
- Connection error handling with user-friendly messages, stale session recovery
- Agent crash detection via close handler, destroying flag, buildCrashChunks
- Port collision: detect EADDRINUSE in vite-plugin stderr and log clear error
- Production Tauri: spawn openpencil-mcp via shell plugin, orphan reuse via health check
- Permission confirmation dialog (reka-ui AlertDialog) with queue, 60s auto-reject timeout
- Health check in ProviderSelect hides ACP agents when MCP server unavailable
- Move DESIGN_CONTEXT to app constants, add ACP_PERMISSION_TIMEOUT_MS
- 36 tests across 3 files (acp-transport, acp-permission, mcp-server)
- Update CHANGELOG, README, CONTRIBUTING, AGENTS.md
2026-03-15 13:37:15 +00:00
### Coding agents (desktop)
Use Claude Code, Codex, or Gemini CLI directly in the chat panel. The agent connects to the editor's MCP server and uses all 90+ design tools. Requires the desktop app and the agent CLI installed locally.
2026-03-15 15:13:29 +00:00
**Setup (Claude Code):**
1. Install the ACP adapter: `npm i -g @zed-industries/claude-agent-acp`
2. Add MCP permission to `~/.claude/settings.json` :
```json
{
"permissions": {
"allow": ["mcp__open-pencil"]
}
}
```
3. Open the desktop app → < kbd > Ctrl</ kbd >< kbd > J</ kbd > → select **Claude Code** from the provider dropdown
2026-03-08 07:46:38 +00:00
### MCP server
2026-03-02 10:57:03 +00:00
2026-03-28 12:42:21 +00:00
Connect Claude Code, Cursor, Windsurf, or any MCP client to inspect, modify, and export design documents headlessly. 90 tools (87 core + 3 file management). [Full docs → ](https://openpencil.dev/reference/mcp-tools )
2026-03-08 07:46:38 +00:00
**Stdio** (Claude Code, Cursor, Windsurf):
2026-03-02 10:57:03 +00:00
2026-03-02 11:28:56 +00:00
```sh
bun add -g @open -pencil/mcp
```
2026-03-02 10:57:03 +00:00
```json
{
"mcpServers": {
"open-pencil": {
2026-03-02 11:28:56 +00:00
"command": "openpencil-mcp"
2026-03-02 10:57:03 +00:00
}
}
}
```
2026-03-08 07:46:38 +00:00
**HTTP** (scripts, CI):
2026-03-02 10:57:03 +00:00
```sh
2026-03-02 11:28:56 +00:00
openpencil-mcp-http # http://localhost:3100/mcp
2026-03-02 10:57:03 +00:00
```
2026-03-08 07:46:38 +00:00
### AI agent skill
Add AI agent skill to README and docs
- README: new 'AI Agent Skill' section with install command
- MCP tools reference: skill section, fix tool count 78→90,
add 10 missing tools (export_image, export_svg, flatten_nodes,
list_fonts, page_bounds, set_layout_child, set_text_properties,
viewport_get, viewport_set, viewport_zoom_to_fit)
- Features page: mention skill with install command
- All 6 locales updated
2026-03-07 22:08:28 +00:00
Teach your AI coding agent to use OpenPencil — inspect designs, export assets, analyze tokens, modify .fig files:
```sh
npx skills add open-pencil/skills@open-pencil
```
Works with Claude Code, Cursor, Windsurf, Codex, and any agent that supports [skills ](https://skills.sh ).
2026-03-08 07:46:38 +00:00
## Collaboration
2026-02-28 05:12:18 +00:00
2026-03-08 07:46:38 +00:00
Share a link to co-edit in real time. No server, no account — peers connect directly via WebRTC.
2026-02-28 05:14:28 +00:00
2026-03-08 07:46:38 +00:00
1. Click the share button in the top-right panel
2. Share the generated link (`app.openpencil.dev/share/< room-id > `)
3. Collaborators see your cursor, selection, and edits in real time
4. Click a peer's avatar to follow their viewport
2026-02-28 05:14:28 +00:00
2026-03-08 07:46:38 +00:00
## Why
2026-02-28 05:14:28 +00:00
2026-03-08 07:46:38 +00:00
Figma is a closed platform that actively fights programmatic access. Their MCP server is read-only. [figma-use ](https://github.com/dannote/figma-use ) added full read/write automation via CDP — then [Figma 126 killed CDP ](https://forum.figma.com/report-a-problem-6/remote-debugging-port-not-working-in-figma-desktop-126-1-2-50858 ). Your design files are in a proprietary binary format that only their software can fully read. Your workflows break when they decide to ship a point release.
2026-02-28 05:12:18 +00:00
2026-03-08 07:46:38 +00:00
OpenPencil is the alternative: open source (MIT), reads .fig files natively, every operation is scriptable, and your data never leaves your machine.
2026-02-28 05:14:28 +00:00
2026-03-08 07:46:38 +00:00
## Roadmap
2026-02-28 08:38:27 +00:00
2026-03-09 14:43:11 +00:00
- Prototyping — frame transitions, interaction triggers, overlay management, preview mode
2026-03-08 07:46:38 +00:00
- Shader effects (SkSL) — custom visual effects via GPU shaders
- Raster tile caching — instant zoom/pan for complex documents
2026-03-09 14:43:11 +00:00
- Component libraries — publish, share, and consume design systems across files
2026-03-08 07:46:38 +00:00
- CI tools — design linting, code export, visual regression in pipelines
2026-03-09 14:43:11 +00:00
- Grid child positioning UI — column/row span controls, grid overlay on canvas
- Skewing and OkHCL color support
- Windows code signing (Azure Authenticode certificates)
2026-02-28 08:38:27 +00:00
2026-03-08 07:46:38 +00:00
## Contributing
2026-02-28 08:38:27 +00:00
2026-03-08 07:46:38 +00:00
### Setup
2026-02-28 08:38:27 +00:00
```sh
2026-03-08 07:46:38 +00:00
bun install
bun run dev # Dev server at localhost:1420
bun run tauri dev # Desktop app (requires Rust)
2026-02-28 08:38:27 +00:00
```
2026-03-08 07:46:38 +00:00
### Quality gates
| Command | Description |
|---------|-------------|
| `bun run check` | Lint + typecheck |
| `bun run test` | E2E visual regression |
| `bun run test:unit` | Unit tests |
| `bun run format` | Code formatting |
2026-02-28 08:38:27 +00:00
2026-03-08 07:46:38 +00:00
### Project structure
2026-02-28 05:12:18 +00:00
```
2026-02-28 22:28:24 +00:00
packages/
2026-03-28 12:45:11 +00:00
core/ @open -pencil/core — engine (scene graph, renderer, layout, file formats, tools)
vue/ @open -pencil/vue — headless Vue SDK
2026-03-08 07:46:38 +00:00
cli/ @open -pencil/cli — headless CLI
2026-03-02 10:57:03 +00:00
mcp/ @open -pencil/mcp — MCP server (stdio + HTTP)
2026-03-08 07:46:38 +00:00
docs/ Documentation site (openpencil.dev)
src/ Vue app (components, composables, stores)
2026-02-28 05:12:18 +00:00
desktop/ Tauri v2 (Rust + config)
2026-03-08 07:46:38 +00:00
tests/ E2E (188 tests) + unit (764 tests)
```
### Tech stack
| Layer | Tech |
|-------|------|
| Rendering | Skia (CanvasKit WASM) |
2026-03-09 14:43:11 +00:00
| Layout | Yoga WASM (flex + grid via [fork ](https://github.com/open-pencil/yoga/tree/grid )) |
2026-03-08 07:46:38 +00:00
| UI | Vue 3, Reka UI, Tailwind CSS 4 |
| File format | Kiwi binary + Zstd + ZIP |
| Collaboration | Trystero (WebRTC P2P) + Yjs (CRDT) |
| Desktop | Tauri v2 |
2026-03-09 14:43:11 +00:00
| AI/MCP | Multi-provider (Anthropic, OpenAI, Google AI, OpenRouter), MCP SDK, Hono |
2026-03-08 07:46:38 +00:00
### Desktop builds
Requires [Rust ](https://rustup.rs/ ) and platform-specific prerequisites ([Tauri v2 guide](https://v2.tauri.app/start/prerequisites/)).
```sh
bun run tauri build
2026-02-28 05:12:18 +00:00
```
2026-03-02 09:27:05 +00:00
## Acknowledgments
Thanks to [@sld0Ant ](https://github.com/sld0Ant ) (Anton Soldatov) for creating and maintaining the [documentation site ](https://openpencil.dev ).
2026-02-28 05:12:18 +00:00
## License
MIT