Skip to content

Repository files navigation

Plane

2026-05-09_01-00-37.mp4

A live design & prototyping desktop tool. Every design is a real React app running in a sandboxed Vite dev server — not a simulation, the actual app. The design artifact and the shipped artifact are the same thing.

What is it

Plane is an Electron app that turns design into code-as-canvas. Designers manipulate components on an infinite canvas through a transparent edit overlay; every change writes back to disk as Tailwind classes via AST-aware source edits. Developers can open the same project in any editor at any time — the files are just files.

  • Visual first, code always. The visual editor is primary; source is real, accessible, and never hidden.
  • Disk-native. Each project is a standard React + TypeScript + Tailwind app — no proprietary format.
  • Non-destructive. Every visual edit has a representation on disk.
  • Speed is a feature. Sub-frame visual edits, ~300ms server respawn, 60fps canvas.

Core concepts

  • Canvas — infinite, pannable, zoomable surface; each frame is a live iframe.
  • Project — a real directory backed by a Vite dev server with HMR.
  • Frame — a viewport onto a project (route + size). One project, many frames, one server.
  • Edit layer — transparent overlay for select / drag / resize / inline text / gap+padding adjustment.
  • Layer tree & property panel — DOM-sourced tree with reorder + reparent DnD; properties expressed as design language (color, size, spacing, weight) rather than raw classes.
  • AI agent (planned) — context-aware prompt bar producing surgical diffs over component source.
  • Snapshots (planned) — timeline / branching of canvas state.

Architecture

plane/
├── apps/
│   └── native/                # Electron app (main + preload + renderer)
│       ├── src/main.ts        # IPC, workspace persistence, source writes
│       ├── src/canvas/        # Canvas + edit overlay + frame interactions
│       ├── src/panels/        # Layer tree + property panel
│       └── resources/project-template/
│           └── src/plane-bridge.ts  # In-iframe postMessage bridge
└── packages/
    ├── bridge/                # Typed IPC contracts + wrappers
    ├── logger/                # Pino-based structured logging
    ├── project-core/          # Shared domain types + project creation
    ├── server-manager/        # Vite lifecycle + compile-time Plane ID plugin
    └── ui/                    # Shared shadcn (base-nova) components

How it interworks

  1. Project lifecycle — renderer calls project:create over typed IPC; main copies the template, installs deps, returns ProjectMeta. Workspace state persists to ~/.plane/workspaces/default/workspace.json.
  2. Server manager + Vite plugin@plane/server-manager allocates ports (5200–5300) and starts a Vite server per project. The injected planeSourceIds() plugin rewrites JSX/TSX under /src to add stable IDs:
    • data-plane-id (p_*) — intrinsic DOM elements
    • data-plane-cid (c_*) — component instance usages
    • data-plane-tid (t_*) — template elements inside component definitions
    • Composite c_xxxx.t_yyyy resolves instance-scoped template targets via GET /__plane/resolve-id.
  3. Iframe bridge — every project imports src/plane-bridge.ts, which answers postMessage commands for selection, tree extraction, class reads/writes, inline text editing, and rect observation, and emits plane:hmr-update after Vite HMR.
  4. Edit pipeline — overlay does immediate in-iframe preview, then commits via typed IPC (source:update-text, source:update-class, source:reorder-children, source:move-element). Main applies AST edits with oxc-parser; HMR propagates to all frames.

Tech stack

  • Desktop shell — Electron 41 + Electron Forge + Vite
  • Renderer — React 19, TypeScript, Tailwind CSS 4
  • UI — shadcn (base-nova) via @plane/ui
  • State — Zustand
  • Drag & drop@atlaskit/pragmatic-drag-and-drop
  • ASToxc-parser
  • Monorepo — pnpm (hoisted, required by Electron Forge) + Turborepo
  • Formatting — oxfmt

Development

pnpm install         # install dependencies
pnpm run dev         # start all apps via turbo
pnpm run build       # build all packages
pnpm run typecheck   # typecheck everything
pnpm run fmt         # format with oxfmt

Linux / Wayland

The dev script passes --ozone-platform=wayland to Electron for crisp rendering on Wayland. turbo.json forwards WAYLAND_DISPLAY, XDG_RUNTIME_DIR, XDG_SESSION_TYPE, and DISPLAY through globalPassThroughEnv.

Status

The core interactive editor loop is implemented:

  • multi-project canvas with pan / zoom
  • frame creation, presets, route editing
  • per-project Vite server orchestration
  • visual element selection + inline text edit
  • element resize + flex gap manipulation
  • layer tree DnD reorder / reparent
  • source-of-truth write-back to TSX via AST-aware utilities
  • workspace persistence + restore

Planned: AI prompt bar integration, snapshot timeline / branching UX, viewport virtualization and server suspension.

Conventions

  • Conventional commits (feat:, fix:, chore:, docs:, refactor:). No co-author trailers.
  • Use @plane/logger — never console.*.
  • Prefer type over interface; avoid any, non-null assertions, and nested ternaries.
  • See AGENTS.md for the full coding-practices and architecture brief.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages