Contributing
Project Structure
packages/
core/ @open-pencil/core — engine (zero DOM deps)
src/ Scene graph, renderer, layout, codec, kiwi, types
cli/ @open-pencil/cli — headless CLI for .fig operations
src/commands/ info, tree, find, export, eval, analyze
mcp/ @open-pencil/mcp — MCP server for AI tools
src/ stdio + HTTP (Hono) transports, 87 tools
src/
components/ Vue SFCs (canvas, panels, toolbar, color picker)
properties/ Property panel sections (Appearance, Fill, Stroke, etc.)
composables/ Canvas input, keyboard shortcuts, rendering hooks
stores/ Editor state (Vue reactivity)
engine/ Re-export shims from @open-pencil/core
kiwi/ Re-export shims from @open-pencil/core
types.ts Shared types (re-exported from core)
constants.ts UI colors, defaults, thresholds
desktop/ Tauri v2 (Rust + config)
tests/
e2e/ Playwright visual regression
engine/ Unit tests (bun:test)
docs/ VitePress documentation siteDevelopment Setup
sh
bun install
bun run dev # Editor at localhost:1420
bun run docs:dev # Docs at localhost:5173Code Style
Tooling
| Tool | Command | Purpose |
|---|---|---|
| oxlint | bun run lint | Linting (Rust-based, fast) |
| oxfmt | bun run format | Code formatting |
| tsgo | bun run typecheck | Type checking (Go-based TypeScript checker) |
Run all checks:
sh
bun run checkConventions
- File names — kebab-case (
scene-graph.ts,use-canvas-input.ts) - Components — PascalCase Vue SFCs (
EditorCanvas.vue,ScrubInput.vue) - Constants — SCREAMING_SNAKE_CASE
- Functions/variables — camelCase
- Types/interfaces — PascalCase
AI Agent Conventions
Developers and AI agents working on the codebase should read AGENTS.md in the repo root (view on GitHub). Covers rendering, scene graph, components & instances, layout, UI, file format, Tauri conventions, and known issues.
Making Changes
- Implement the change
- Run
bun run checkandbun run test - Submit a pull request
Key Files
Core engine source lives in packages/core/src/. App-specific editor, document, AI, collaboration, shell, demo, and automation code lives under src/app/*; the Vue SDK owns reusable canvas/composable code under packages/vue/src/.
| File | Purpose |
|---|---|
packages/core/src/scene-graph/ | Scene graph: nodes, variables, instances, hit testing |
packages/core/src/canvas/renderer.ts | CanvasKit rendering pipeline |
packages/core/src/layout.ts | Yoga layout adapter |
packages/core/src/scene-graph/undo.ts | Undo/redo manager |
packages/core/src/clipboard.ts | Figma-compatible clipboard |
packages/core/src/vector/ | Vector network model |
packages/core/src/io/formats/raster/render.ts | Offscreen image export (PNG/JPG/WEBP) |
packages/core/src/kiwi/binary/codec.ts | Kiwi binary encoder/decoder |
packages/core/src/kiwi/fig-import.ts | .fig file import logic |
packages/cli/src/index.ts | CLI entry point |
packages/core/src/tools/ | Unified tool definitions split by domain (read, create, modify, structure, variables, vector, analyze) |
packages/core/src/figma-api/ | Figma Plugin API implementation |
packages/mcp/src/server.ts | MCP server factory |
packages/cli/src/commands/ | CLI commands (info, tree, find, export, eval, analyze) |
src/app/editor/session/create.ts | Editor session assembly |
packages/vue/src/canvas/CanvasRoot.vue | Canvas rendering composable |
packages/vue/src/canvas/useCanvasInput.ts | Mouse/touch input handling |
src/app/shell/keyboard/use.ts | Keyboard shortcut handling |