The world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
Find a file
Kayshen Xu 7271a03833
V0.7.1 (#103)
* fix(desktop,web): rebuild Electron dev sync + bitmap dragging fix on v0.7.1 (#99)

Re-applies b046a0d from the closed PR #97 now that the base is v0.7.1.
Original conflict against v0.7.0 came from the release branch churn —
the cherry-pick onto v0.7.1 applies cleanly.

Keeps dev-startup, sync-noise, and bitmap-dragging fixes; drops the
loopback proxy helper scripts upstream rejected in PR #92. Readiness
probe now does direct socket checks inside the existing dev entrypoint;
sync hardening stays focused on request diagnostics, backpressure, and
drag-time clip-rect correctness.

Original commit: b046a0d
Supersedes: #97 (closed, head branch deleted)

Co-authored-by: Rais <vdcoolzi@gmail.com>

* fix(canvas): use ImageFill.url in skia-interaction test

The image-backed rectangle fixture in the skia-interaction test used
`{ type: 'image', src: '…' }`, but `ImageFill` in pen-types declares
the field as `url`. `npx tsc --noEmit` flagged it as TS2352 on the
`as PenNode` cast. One-word rename.

The squash-merge of #99 captured an earlier snapshot that did not
include this fix, so re-apply directly on v0.7.1.

* feat(cli): add `op install` / `op uninstall` for openpencil-skill

Bundle skill files at build time (scripts/bundle-skill.ts → skill-bundle.json)
so users without GitHub access can install directly. Falls back to git clone
when the bundle is empty.

Supports auto-detection of: Claude Code, Codex, Cursor, Gemini CLI, OpenCode.
CI workflows updated to checkout openpencil-skill before cli:compile.

* fix(panels): allow reparenting nodes into rectangle in layer panel

CONTAINER_TYPES was missing 'rectangle', preventing drag-drop into
rectangles even though the data model (ContainerProps) and store
(moveNode) both support it.

* fix(agent,ai): tool_exec reset + insert_node with after + move_node + CRUD tools

- fix(agent): reset StreamingToolExecutor between turns — prevents stale
  tool_use IDs that caused 400 errors on multi-turn tool calls (MiniMax etc.)
- feat(ai): add insert_node "after" parameter — auto-resolves sibling's
  parent and position for intuitive node insertion
- feat(ai): add move_node and insert_node to CRUD tool set
- feat(ai): add Chinese keywords (增加/添加/插入) to design intent detection
- fix(ai): insert_node uses addNode directly for existing parents instead
  of streaming pipeline, fixing parent resolution

* feat(ai): route CRUD intents to lightweight prompt and tool set

CRUD operations (read/update/delete) now get a focused system prompt
without design generation instructions, and use getCrudToolDefs()
(which includes insert_node and move_node) instead of the full design set.

* fix(agent,mcp): submodule update + MCP tool improvements

- Update agent-native submodule (tool_exec reset, HTTP error diagnostics)
- Improve MCP tool descriptions and parameter schemas
- Enhance agent.ts error handling

* feat(ai): add PenNode examples to CRUD prompt for complete node generation

The CRUD system prompt now includes button and text node examples
showing the full structure (fills, children, icons, layout) so models
generate complete nodes instead of empty frames.

* Update agent-native submodule to commit f9633a8, ensuring compatibility with recent changes and improvements in the agent's functionality.

* fix(ci,agent): generate skill-bundle before type check + fix moveNode arg

- Add `bun run cli:bundle-skill` step in CI before `tsc --noEmit` so
  skill-bundle.json exists when type-checking the CLI
- Fix moveNode index parameter: default to -1 when undefined

* fix(ci): add pen-engine and pen-react to npm publish workflow

Insert pen-engine and pen-react in topological order between
pen-renderer and pen-mcp so they are published before pen-sdk.

* docs: add MIT LICENSE and README to all packages

- Add MIT LICENSE to pen-ai-skills, pen-core, pen-engine, pen-figma,
  pen-mcp, pen-react, pen-renderer, pen-sdk, pen-types
- Add README.md to pen-engine, pen-react, pen-mcp, pen-ai-skills

* docs: comprehensive package metadata, README, CLAUDE.md, and LICENSE

- Add author, license, repository, bugs, homepage to all package.json
- Homepage points to each package's own directory on GitHub
- Rewrite README for pen-engine, pen-react, pen-mcp, pen-ai-skills
  with full API docs, usage examples, and feature tables
- Add CLAUDE.md to pen-types, pen-core, pen-engine, pen-figma,
  pen-mcp, pen-react, pen-renderer, pen-sdk
- Add MIT LICENSE to all packages
- Update root CLAUDE.md with index of all sub-CLAUDE.md files
- Fix git URL from nicepkg → ZSeven-W

* docs: package metadata, README, LICENSE, and CLAUDE.md for all packages

- Add author, license, repository, bugs, homepage to all package.json
- Homepage points to each package's own directory on GitHub
- Rewrite README for pen-engine, pen-react, pen-mcp, pen-ai-skills
  with full API docs, usage examples, and feature tables
- Add MIT LICENSE to all packages missing it
- Add CLAUDE.md to pen-types
- Update root CLAUDE.md with index of all sub-CLAUDE.md files
- Fix git URL from nicepkg to ZSeven-W

* docs: rewrite README for pen-core, pen-figma, pen-renderer, pen-sdk

Comprehensive READMEs with full API reference, usage examples,
feature tables, and architecture overview for each package.

* feat(acp): acpAgents store — persist, hydrate, CRUD actions

* feat(acp): pen-acp package + agent settings types + store

- pen-acp/types.ts: AcpAgentConfig, AcpAgentInfo, AcpConnectResult, AcpConnectionState
- pen-acp/client.ts: connectAcpAgent (local stdio + remote WebSocket), disconnectAcpAgent
- pen-acp/event-adapter.ts: acpUpdateToSSE (ACP session/update → SSE events)
- agent-settings.ts: AcpAgentConfig type, widen ModelGroup/GroupedModel.provider
- agent-settings-store.ts: acpAgents persist/hydrate/CRUD + acpConnectionStatus

* fix(acp): remove unused type imports in client.ts

* feat(acp): ACP agent settings UI — form, cards, connect/disconnect

* feat(acp): add AcpAgentSection to Agents settings tab

* refactor(agent): AgentSession as discriminated union (native | acp)

* feat(acp): connection manager — connect, disconnect, cleanup

* feat(acp): connect/disconnect API route

* feat(acp): ACP branch in agent result handler

* fix(agent): use NativeAgentSession type for runDelegateMember

* feat(acp): ACP prompt SSE stream in agent endpoint

* feat(acp): ACP agents in model list + request routing

* i18n(acp): add ACP agent translation keys for all 15 locales

* fix(i18n): translate ACP keys for all 15 locales + fix missing key references

- zh.ts/zh-tw.ts: proper Chinese translations (Agent not translated)
- All other locales: translated from English placeholders
- Fix acp.add → acp.addAgent, acp.disconnected → acp.notConnected

* chore: bump agent-native submodule — surface upstream HTTP errors

* feat(acp,build,codegen): comprehensive fixes for ACP integration + prod build

ACP agent integration:
- Rewrite system prompt to enforce layered design pipeline (get_design_prompt
  → design_skeleton → design_content → design_refine) for higher quality output
- Use correct PenNode field names: content for text, iconFontName for icons
- Strict JSON rules to prevent empty-key / trailing-comma / smart-quote errors
- Prefer icon_font over path icons (standalone MCP has no hooks registered)
- Auto-start MCP server before ACP session (lazy bootstrap)
- Auto-reconnect ACP on stale connection (dev server restart scenario)
- Auto-approve tool permission requests (trust model: user configured agent)
- Use type: 'http' + headers: [] for MCP server config (SDK schema requirement)
- Persist ACP connections via globalThis so they survive Vite HMR

Build / packaging:
- Place agent-native under server/node_modules for Nitro to resolve at runtime
- Copy agent_napi.node to napi/ as extraResource
- Kill detached MCP server on Electron quit (before-quit + dev SIGINT handlers)
- Capture drag-dropped filesystem path via webUtils.getPathForFile so recent
  files entries are clickable after reopening

Codegen:
- Compact JSON (no indent) + strip noise fields (id, parentId, default rotation
  /opacity/visible, layout-managed x/y) to reduce request body size by 60-70%
  so proxies don't reject with 403 'Request not allowed'

MCP batch_design robustness:
- splitOperations tracks bracket/quote balance → multi-line JSON now works
- Auto-normalize fill/stroke shorthand forms
- Collect per-line errors instead of aborting whole batch
- Repair empty keys, trailing commas, smart quotes in JSON
- Bindless I(...) form supported (auto-generates binding)

UI:
- ModelDropdown / ChatInput handle ACP model icons (Plug)
- Reset streaming state + abort controller on ACP error path
- Strip h3 JSON error wrapper so chat shows clean error messages
- ACP agent settings form + cards + connect/disconnect

* fix(types): resolve TS errors in CI typecheck

- acp-connection-manager.ts: correct relative import path (utils/ → src/types)
- ai-chat-handlers.ts: cast currentProvider to AIProviderType at design-generator callsites
- ai-chat-panel.tsx: explicitly type groups as ModelGroup[] so 'acp' string fits the widened union
- acp-agent-settings.tsx: cast window through unknown for Record lookup
- electron.d.ts: add getPathForFile to ElectronAPI declaration
- builtin-provider-presets.ts: drop now-redundant config.preset !== 'custom' check (handled by early return)
- pen-acp/client.ts: cast Writable/Readable.toWeb to typed Streams; coerce nullish agentInfo fields to undefined

* fix(ci): checkout openpencil-skill into workspace subdirectory

GitHub Actions rejects checkout paths outside the runner workspace.
Move from ../openpencil-skill to external/openpencil-skill and pass
SKILL_ROOT env to the bundle script so it can locate the cloned repo.

* chore(ci): checkout openpencil-skill in ci workflow

Bundle the real skill contents in CI builds instead of falling back
to the empty bundle. Mirrors the checkout pattern used by the
electron and npm publish workflows.

---------

Co-authored-by: Rais <vdcoolzi@gmail.com>
2026-04-13 21:40:40 +08:00
.githooks V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
.github V0.7.1 (#103) 2026-04-13 21:40:40 +08:00
.vscode V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
apps V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
packages V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
screenshot docs(readme): update cover screenshot 2026-04-13 21:15:00 +08:00
scripts V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
.cta.json V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
.dockerignore V0.5.0 (#71) 2026-03-22 10:09:26 +08:00
.editorconfig V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
.gitignore V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
.gitmodules V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
.oxfmtrc.json V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
.prettierignore V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
AGENTS.md V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
bun.lock V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
CLAUDE.md V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
Dockerfile V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
LICENSE chore: update documentation and add MIT License 2026-02-18 22:35:17 +08:00
oxlintrc.json V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
package.json V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
README.de.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.es.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.fr.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.hi.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.id.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.ja.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.ko.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.pt.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.ru.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.th.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.tr.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.vi.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.zh-TW.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
README.zh.md docs(readme): v0.7.0 feature sweep, circular sponsor avatar, 15-locale i18n (#98) 2026-04-12 09:21:35 +08:00
tsconfig.base.json V0.5.0 (#67) 2026-03-22 09:44:04 +08:00
tsconfig.json V0.7.0 (#95) 2026-04-11 23:25:13 +08:00

OpenPencil

OpenPencil

The world's first open-source AI-native vector design tool.
Concurrent Agent Teams • Design-as-Code • Built-in MCP Server • Multi-model Intelligence

English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Français · Español · Deutsch · Português · Русский · हिन्दी · Türkçe · ไทย · Tiếng Việt · Bahasa Indonesia

Stars License CI Discord


OpenPencil — click to watch demo

Click the image to watch the demo video


Note: There is another open-source project with the same name — OpenPencil, focused on Figma-compatible visual design with real-time collaboration. This project focuses on AI-native design-to-code workflows.

Why OpenPencil

🎨 Prompt → Canvas

Describe any UI in natural language. Watch it appear on the infinite canvas in real-time with streaming animation. Modify existing designs by selecting elements and chatting.

🤖 Concurrent Agent Teams

The orchestrator decomposes complex pages into spatial sub-tasks. Multiple AI agents work on different sections simultaneously — hero, features, footer — all streaming in parallel with per-member canvas indicators.

🧠 Multi-Model Intelligence

Automatically adapts to each model's capabilities. Claude gets full prompts with thinking; GPT-4o/Gemini disable thinking; smaller models (MiniMax, Qwen, Llama) get simplified prompts for reliable output.

🔌 MCP Server

One-click install into Claude Code, Codex, Gemini, OpenCode, Kiro, or Copilot CLIs. Design from your terminal — read, create, and modify .op files through any MCP-compatible agent.

🎨 Style Guides

Built-in style guide library with tag-based fuzzy matching. Apply visual styles (glassmorphism, brutalist, retro, etc.) to AI-generated designs. MCP tools for external agent access.

📦 Design-as-Code

.op files are JSON — human-readable, Git-friendly, diffable. Design variables generate CSS custom properties. Code export to React + Tailwind or HTML + CSS.

🖥️ Runs Everywhere

Web app + native desktop on macOS, Windows, and Linux via Electron. Auto-updates from GitHub Releases. .op file association — double-click to open.

⌨️ CLI — op

Control the design tool from your terminal. op design, op insert, op export — batch design DSL, node manipulation, code export. Pipe in from files or stdin. Works with desktop app or web server.

🎯 Multi-Platform Code Export

Export to React + Tailwind, HTML + CSS, Vue, Svelte, Flutter, SwiftUI, Jetpack Compose, React Native — all from one .op file. Design variables become CSS custom properties.

🧩 Embeddable SDK

pen-engine (headless) + pen-react (React UI SDK) — embed the design engine in your own app. DesignProvider, DesignCanvas, hooks, panels, and toolbar components out of the box.

🛡️ Design System Kit

Manage reusable UIKits with style switching and component composition. Import/export kits from .pen files. Built-in registry with MCP tools for external access.

Install

macOS (Homebrew):

brew tap zseven-w/openpencil
brew install --cask openpencil

Windows (Scoop):

scoop bucket add openpencil https://github.com/zseven-w/scoop-openpencil
scoop install openpencil

Linux / Windows direct download: GitHub Releases.exe (Windows), .AppImage / .deb (Linux)

CLI (op):

npm install -g @zseven-w/openpencil

Quick Start (Development)

# Install dependencies
bun install

# Start dev server at http://localhost:3000
bun --bun run dev

Or run as a desktop app:

bun run electron:dev

Prerequisites: Bun >= 1.0 and Node.js >= 18. Optional: Zig >= 0.14 for building agent-native from source (a prebuilt binary will be downloaded automatically if Zig is not installed).

Docker

Multiple image variants are available — pick the one that fits your needs:

Image Size Includes
openpencil:latest ~226 MB Web app only
openpencil-claude:latest + Claude Code CLI
openpencil-codex:latest + Codex CLI
openpencil-opencode:latest + OpenCode CLI
openpencil-copilot:latest + GitHub Copilot CLI
openpencil-gemini:latest + Gemini CLI
openpencil-full:latest ~1 GB All CLI tools

Run (web only):

docker run -d -p 3000:3000 ghcr.io/zseven-w/openpencil:latest

Run with AI CLI (e.g. Claude Code):

The AI chat relies on Claude CLI OAuth login. Use a Docker volume to persist the login session:

# Step 1 — Login (one-time)
docker volume create openpencil-claude-auth
docker run -it --rm \
  -v openpencil-claude-auth:/root/.claude \
  ghcr.io/zseven-w/openpencil-claude:latest claude login

# Step 2 — Start
docker run -d -p 3000:3000 \
  -v openpencil-claude-auth:/root/.claude \
  ghcr.io/zseven-w/openpencil-claude:latest

Build locally:

# Base (web only)
docker build --target base -t openpencil .

# With a specific CLI
docker build --target with-claude -t openpencil-claude .

# Full (all CLIs)
docker build --target full -t openpencil-full .

AI-Native Design

Prompt to UI

  • Text-to-design — describe a page, get it generated on canvas in real-time with SSE streaming animation
  • Orchestrator — decomposes complex pages into spatial sub-tasks for parallel generation
  • Agent Teams — concurrent team members with delegate tool, per-member canvas indicators, and fallback strategies
  • Design modification — select elements, then describe changes in natural language
  • Vision input — attach screenshots or mockups for reference-based design
  • Style Guides — apply visual styles (glassmorphism, brutalist, retro, etc.) via tag-based fuzzy matching
  • Anti-slop — cross-generation diversity tracking to avoid repetitive AI output

Multi-Agent Support

Agent Setup
Built-in (9+ providers) Select from provider presets with region switcher — Anthropic, OpenAI, Google, DeepSeek, and more
Claude Code No config — uses Claude Agent SDK with local OAuth
Codex CLI Connect in Agent Settings (Cmd+,)
OpenCode Connect in Agent Settings (Cmd+,)
GitHub Copilot copilot login then connect in Agent Settings (Cmd+,)
Gemini CLI Connect in Agent Settings (Cmd+,)

Model Capability Profiles — automatically adapts prompts, thinking mode, and timeouts per model tier. Full-tier models (Claude) get complete prompts; standard-tier (GPT-4o, Gemini, DeepSeek) disable thinking; basic-tier (MiniMax, Qwen, Llama, Mistral) get simplified nested-JSON prompts for maximum reliability.

i18n — Full interface localization in 15 languages: English, 简体中文, 繁體中文, 日本語, 한국어, Français, Español, Deutsch, Português, Русский, हिन्दी, Türkçe, ไทย, Tiếng Việt, Bahasa Indonesia.

MCP Server

  • Built-in MCP server (pen-mcp package) — one-click install into Claude Code / Codex / Gemini / OpenCode / Kiro / Copilot CLIs
  • Auto-detects Node.js — if not installed, falls back to HTTP transport and auto-starts the MCP HTTP server
  • Design automation from terminal: read, create, and modify .op files via any MCP-compatible agent
  • Layered design workflowdesign_skeletondesign_contentdesign_refine for higher-fidelity multi-section designs
  • Segmented prompt retrieval — load only the design knowledge you need (schema, layout, roles, icons, planning, etc.)
  • Style guide toolsget_style_guide_tags and get_style_guide for applying visual styles via MCP
  • Multi-page support — create, rename, reorder, and duplicate pages via MCP tools

Code Generation

  • React + Tailwind CSS, HTML + CSS, CSS Variables
  • Vue, Svelte, Flutter, SwiftUI, Jetpack Compose, React Native

CLI — op

Install globally and control the design tool from your terminal:

npm install -g @zseven-w/openpencil
op start                     # Launch desktop app
op design @landing.txt       # Batch design from file
op insert '{"type":"RECT"}'  # Insert a node
op export react --out .      # Export to React + Tailwind
op import:figma design.fig   # Import Figma file
cat design.dsl | op design - # Pipe from stdin

Supports three input methods: inline string, @filepath (read from file), or - (read from stdin). Works with desktop app or web dev server. See CLI README for full command reference.

LLM Skill — install the OpenPencil Skill plugin to teach AI agents (Claude Code, Cursor, Codex, Gemini CLI, etc.) how to design with op.

Features

Canvas & Drawing

  • Infinite canvas with pan, zoom, smart alignment guides, and snapping
  • Rectangle, Ellipse, Line, Polygon, Pen (Bezier), Frame, Text
  • Boolean operations — union, subtract, intersect with contextual toolbar
  • Icon picker (Iconify) and image import (PNG/JPEG/SVG/WebP/GIF)
  • Auto-layout — vertical/horizontal with gap, padding, justify, align
  • Multi-page documents with tab navigation

Design System

  • Design variables — color, number, string tokens with $variable references
  • Multi-theme support — multiple axes, each with variants (Light/Dark, Compact/Comfortable)
  • Component system — reusable components with instances and overrides
  • CSS sync — auto-generated custom properties, var(--name) in code output
  • Reusable UIKits — import/export component kits from .pen files

AI & Agents

  • Prompt-to-canvas with streaming generation and orchestrator-driven spatial decomposition
  • Concurrent Agent Teams — multiple designers work on different sections in parallel with per-member canvas indicators
  • Layered workflow — design_skeletondesign_contentdesign_refine with focused prompts per phase
  • Style Guides — 50+ built-in styles (glassmorphism, brutalist, retro, etc.) with tag-based fuzzy matching, wired into planning and generation
  • Multi-model capability profiles — auto-adapts thinking mode, effort, and prompt shape per model tier
  • Built-in agent runtime (agent-native, Zig NAPI) + Anthropic, Claude Agent SDK, OpenCode, Codex, Copilot, Gemini providers
  • Anthropic-format passthrough for Chinese LLM providers — Kimi, Zhipu, GLM, DouBao, Ark, Bailian/DashScope, ModelScope, Coding Plans

Git Integration

  • Clone wizard with SSH / HTTPS auth and SSH key management
  • Branch picker — create, switch, delete, merge, all from the git panel
  • Pull / push cascades with auth retry and non-fast-forward handling
  • Folder-mode three-way merge with on-disk MERGE_HEAD state tracking
  • Conflict panel with per-node / per-field three-way cards, inline JSON editor, bulk actions, and inline diff block
  • Remote settings and SSH keys UI; 15-locale i18n across the whole Git surface

Export

  • Canvas export — PNG, JPEG, WEBP, PDF (Cmd+Shift+P)
  • Code export — React + Tailwind, HTML + CSS, Vue, Svelte, Flutter, SwiftUI, Jetpack Compose, React Native
  • Incremental MCP codegen pipeline — codegen_plan, codegen_submit_chunk, codegen_assemble, codegen_clean

Figma Import

  • Import .fig files with layout, fills, strokes, effects, text, images, and vectors preserved

Desktop App

  • Native macOS, Windows, and Linux via Electron
  • .op file association — double-click to open, single-instance lock
  • Auto-update from GitHub Releases
  • Native application menu with Save As, Open Recent, and an unsaved-changes dialog on close
  • Recent files persistence

Tech Stack

Frontend React 19 · TanStack Start · Tailwind CSS v4 · shadcn/ui · i18next
Canvas CanvasKit/Skia (WASM, GPU-accelerated)
Engine pen-engine (headless) · pen-react (React UI SDK)
State Zustand v5
Server Nitro
Desktop Electron 35
CLI op — terminal control, batch design DSL, code export
AI agent-native (Zig NAPI) · Anthropic SDK · Claude Agent SDK · OpenCode SDK · Copilot SDK
Runtime Bun · Vite 7
Lint oxlint · oxfmt
File format .op — JSON-based, human-readable, Git-friendly

Project Structure

openpencil/
├── apps/
│   ├── web/                 TanStack Start web app
│   │   ├── src/
│   │   │   ├── canvas/      CanvasKit/Skia engine — drawing, sync, layout
│   │   │   ├── components/  React UI — editor, panels, shared dialogs, icons
│   │   │   ├── services/ai/ AI chat, orchestrator, design generation, streaming
│   │   │   ├── services/codegen/ Code generation service wrappers
│   │   │   ├── stores/      Zustand — canvas, document, pages, history, AI
│   │   │   ├── hooks/       Keyboard shortcuts, file drop, Figma paste, MCP sync
│   │   │   ├── i18n/        Internationalization — 15 locales
│   │   │   └── uikit/       Reusable component kit system
│   │   └── server/
│   │       ├── api/ai/      Nitro API — streaming chat, agent, generation, image search
│   │       ├── api/mcp/     MCP HTTP transport endpoints
│   │       └── utils/       Claude, OpenCode, Codex, Copilot, Gemini CLI wrappers
│   ├── desktop/             Electron desktop app
│   │   ├── main.ts          Window, Nitro fork, native menu, auto-updater
│   │   ├── ipc-handlers.ts  Native file dialogs, theme sync, prefs IPC
│   │   └── preload.ts       IPC bridge
│   └── cli/                 CLI tool — `op` command
│       ├── src/commands/    Design, document, export, import, node, page, variable commands
│       ├── connection.ts    WebSocket connection to running app
│       └── launcher.ts      Auto-detect and launch desktop app or web server
├── packages/
│   ├── pen-types/           Type definitions for PenDocument model
│   ├── pen-core/            Document tree ops, layout engine, variables
│   ├── pen-engine/          Headless design engine — document, selection, history, viewport
│   ├── pen-react/           React UI SDK — provider, canvas, hooks, panels, toolbar
│   ├── pen-codegen/         Code generators (React, HTML, Vue, Flutter, ...)
│   ├── pen-figma/           Figma .fig file parser and converter
│   ├── pen-renderer/        Standalone CanvasKit/Skia renderer
│   ├── pen-mcp/             MCP server — tools, routes, document manager
│   ├── pen-sdk/             Umbrella SDK (re-exports all packages)
│   ├── pen-ai-skills/       AI prompt skill engine (phase-driven prompt loading)
│   └── agent-native/        Native AI agent runtime (Zig NAPI, multi-provider, teams)
└── .githooks/               Pre-commit version sync from branch name

Keyboard Shortcuts

Key Action Key Action
V Select Cmd+S Save
R Rectangle Cmd+Z Undo
O Ellipse Cmd+Shift+Z Redo
L Line Cmd+C/X/V/D Copy/Cut/Paste/Duplicate
T Text Cmd+G Group
F Frame Cmd+Shift+G Ungroup
P Pen tool Cmd+Shift+P Export (PNG/JPG/WEBP/PDF)
H Hand (pan) Cmd+Shift+C Code panel
Del Delete Cmd+Shift+V Variables panel
[ / ] Reorder Cmd+J AI chat
Arrows Nudge 1px Cmd+, Agent settings
Cmd+Alt+U Boolean union Cmd+Alt+S Boolean subtract
Cmd+Alt+I Boolean intersect Cmd+Shift+S Save As

Scripts

bun --bun run dev          # Dev server (port 3000)
bun --bun run build        # Production build
bun --bun run test         # Run tests (Vitest)
npx tsc --noEmit           # Type check
bun run lint               # Lint (oxlint)
bun run format             # Format (oxfmt)
bun run bump <version>     # Sync version across all package.json
bun run electron:dev       # Electron dev
bun run electron:build     # Electron package
bun run cli:dev            # Run CLI from source
bun run cli:compile        # Compile CLI to dist
bun run mcp:dev            # Run MCP server from source

Contributing

Contributions are welcome! See CLAUDE.md for architecture details and code style.

  1. Fork and clone
  2. Set up version sync: git config core.hooksPath .githooks
  3. Create a branch: git checkout -b feat/my-feature
  4. Run checks: npx tsc --noEmit && bun --bun run test
  5. Commit with Conventional Commits: feat(canvas): add rotation snapping
  6. Open a PR against main

Roadmap

  • Design variables & tokens with CSS sync
  • Component system (instances & overrides)
  • AI design generation with orchestrator
  • MCP server integration with layered design workflow
  • Multi-page support
  • Figma .fig import
  • Boolean operations (union, subtract, intersect)
  • Multi-model capability profiles
  • Monorepo restructure with reusable packages
  • CLI tool (op) for terminal control
  • Built-in AI agent SDK with multi-provider support
  • i18n — 15 languages
  • Headless design engine (pen-engine) + React UI SDK (pen-react)
  • Style Guides with tag-based matching and MCP tools
  • Concurrent Agent Teams with delegate tool and canvas indicators
  • Native agent runtime (agent-native — Zig NAPI)
  • Git integration — clone, branch, push/pull, folder-mode three-way merge
  • Canvas raster export (PNG / JPEG / WEBP / PDF)
  • Collaborative editing
  • Plugin system

Contributors

Contributors

Sponsors

OpenPencil is free and open-source. Development is funded by people who find it useful — thank you for keeping the canvas open.

MrQyun

Thanks to MrQyun — want your name here too? Become a sponsor →

Community

Discord Join our Discord — Ask questions, share designs, suggest features.

Star History

Star History Chart

License

MIT — Copyright (c) 2026 ZSeven-W