Plane
How Plane Is Built Repository structure, build system, dependencies, deployment pipeline, and developer experience
Plane is built as a pnpm monorepo orchestrated by Turborepo, with React apps, a Django API, a Hocuspocus live server, and Docker-first deployment assets living in one repository. This page explains the repo layout, build pipeline, dependencies, and deployment path that turn the source tree into a running product.
For Product Managers
This page answers "how does the engineering team ship Plane?" — the tools, processes, and infrastructure that turn source code into a running product. Understanding this helps you grasp engineering timelines, deployment complexity, and maintenance costs.
Plane is a pnpm monorepo with Turborepo for build orchestration. All applications and shared packages live in a single Git repository.
plane/
├── apps/
│ ├── web/ ← React SPA — main user interface (port 3000)
│ ├── admin/ ← Admin panel — instance settings (port 3001)
│ ├── space/ ← Public project views — shareable (port 3002)
│ ├── api/ ← Django REST API — all business logic
│ ├── live/ ← Hocuspocus — real-time CRDT server (port 3100)
│ └── proxy/ ← Caddy reverse proxy
├── packages/
│ ├── ui/ ← 84 reusable React components
│ ├── editor/ ← Tiptap/Yjs rich text editor
│ ├── types/ ← 117 TypeScript type definition files
│ ├── constants/ ← Shared enums and config
│ ├── services/ ← API service layer (Axios wrappers)
│ ├── hooks/ ← Shared React hooks
│ ├── shared-state/ ← Shared MobX stores (user, workspace, filters)
│ ├── i18n/ ← Internationalization (20 languages)
│ ├── propel/ ← UI primitives (accordion, charts, combobox)
│ ├── utils/ ← Helper utilities (date, sanitize, markdown)
│ ├── logger/ ← Winston-based logging
│ ├── decorators/ ← Express controller/route decorators
│ ├── tailwind-config/← Shared Tailwind 4.1 configuration
│ ├── typescript-config/ ← Shared TypeScript configs
│ └── codemods/ ← JSCodeshift migration scripts
├── deployments/
│ ├── cli/ ← Docker Compose self-hosted CLI
│ ├── kubernetes/ ← K8s manifests (community maintained)
│ └── aio/ ← All-in-One single container
├── turbo.json ← Turborepo task configuration
├── pnpm-workspace.yaml ← Workspace package definitions
└── package.json ← Root config (pnpm 10.30, Node ≥22.18)
App Technology Purpose web React 18 + React Router 7 + Vite Main user-facing application (1,482 TSX files) admin React 18 + React Router 7 + Vite Instance administration (/god-mode/) space React 18 + React Router 7 + Vite (SSR) Public-facing project views (shareable links) api Django 4.2.29 + DRF 3.15.2 REST API, business logic, database management live Node.js + Hocuspocus 2.15.2 Real-time collaborative editing WebSocket server proxy Caddy 2.10 Reverse proxy with automatic HTTPS
Package Purpose @plane/ui84 reusable UI components (buttons, modals, dropdowns, tables) @plane/editorRich text editor (Tiptap + Yjs CRDT collaboration) @plane/types117 TypeScript type definition files (issues, projects, cycles, etc.) @plane/servicesAPI service layer wrapping Axios HTTP calls @plane/hooksShared React hooks @plane/shared-stateShared MobX stores (user, workspace, rich filters) @plane/i18nInternationalization with ICU message format (20 locales) @plane/constantsShared enums, config values @plane/utilsUtility functions (date-fns, sanitize-html, chroma-js) @plane/propelUI primitives (accordion, charts, combobox, switch) @plane/loggerWinston-based structured logging @plane/decoratorsExpress controller/route decorators (for live server) @plane/tailwind-configShared Tailwind CSS 4.1 configuration @plane/typescript-configShared TypeScript configs @plane/codemodsJSCodeshift codemods for code migrations
Why a Monorepo?
All 6 apps share the same types, components, and utilities. When a developer changes an Issue type definition in @plane/types, all apps see the change immediately — no publishing, no version mismatch. Turborepo ensures only affected packages are rebuilt.
pnpm install ← installs all dependencies across workspaces
│
▼
turbo build ← Turborepo orchestrates parallel builds
│
├──► @plane/types (TypeScript → declarations)
├──► @plane/ui (React components → bundled)
├──► @plane/editor (Editor components → bundled)
│
├──► web (react-router build → production bundle)
├──► admin (react-router build → production bundle)
└──► space (react-router build → production bundle)
Each frontend app uses React Router 7 as a framework (with react-router build instead of Vite directly), producing optimized static + server bundles. The production containers serve these via Nginx .
pip install -r requirements/ ← Python dependencies
│
▼
python manage.py migrate ← apply 126 database migrations
│
▼
gunicorn plane.asgi:app ← start production server (ASGI via uvicorn)
Dependency Version Purpose React 18.3.1 UI framework React Router 7.12.0 Client + server routing MobX 6.12.0 Fine-grained reactive state management SWR 2.2.4 Data fetching with stale-while-revalidate caching Tailwind CSS 4.1.17 Utility-first styling Tiptap 2.22.3 Rich text editor (ProseMirror-based) Yjs 13.6.20 CRDT library for real-time collaboration Vite 7.3.1 Build tool and dev server Axios 1.13.5 HTTP client for API calls Recharts ^2.12.7 Charts and data visualization Lucide React 0.469.0 Icon set Headless UI ^1.7.19 Accessible UI primitives TanStack React Table ^8.21.3 Table component React Hook Form 7.51.5 Form management date-fns ^4.1.0 Date utility library
Dependency Version Purpose Django 4.2.29 Web framework (LTS) DRF 3.15.2 REST API framework Celery 5.4.0 Distributed task queue django-celery-beat 2.6.0 Periodic task scheduler psycopg 3.3.0 PostgreSQL 3 driver redis 5.0.4 Redis/Valkey client django-redis 5.4.0 Django cache backend channels 4.1.0 ASGI support gunicorn 23.0.0 Production WSGI/ASGI server uvicorn 0.29.0 ASGI server boto3 1.34.96 AWS S3 / MinIO integration openai 1.63.2 AI features drf-spectacular 0.28.0 OpenAPI/Swagger documentation nh3 (latest) HTML sanitizer (Rust-based) posthog 3.5.0 Product analytics
Service Version Purpose PostgreSQL 15.7-alpine Primary database Valkey 7.2.11-alpine Cache + session store (Redis-compatible) RabbitMQ 3.13.6-management Celery message broker (AMQP) MinIO latest S3-compatible object storage (self-hosted) Caddy 2.10 Reverse proxy with automatic HTTPS Nginx 1.27/1.29-alpine Static frontend serving inside Docker
docker-compose.yml
├── web → React SPA (Nginx)
├── admin → Admin panel (Nginx)
├── space → Public views (Nginx)
├── api → Django API (Gunicorn)
├── worker → Celery worker
├── beat-worker → Celery beat (scheduled tasks)
├── migrator → Runs DB migrations on startup
├── live → Hocuspocus WebSocket server
├── proxy → Caddy reverse proxy
├── plane-db → PostgreSQL 15.7
├── plane-redis → Valkey 7.2.11
├── plane-mq → RabbitMQ 3.13.6
└── plane-minio → MinIO (S3-compatible storage)
Strategy Target Complexity Docker Compose (CLI) Single server Low — one-line install script Kubernetes K8s cluster High — community-maintained manifests All-in-One Single container Lowest — single Docker image with Supervisor Docker Swarm Multi-node Medium — swarm.sh script
# One-line self-hosted install
curl -fsSL https://raw.githubusercontent.com/makeplane/plane/master/deployments/cli/community/install.sh | bash
Layer Tool Scope Backend pytest 9.0.2 Unit, contract, and smoke tests Frontend Vitest Package-level unit tests Visual Storybook + Chromatic Component visual regression Codemods Vitest Migration script testing
Tool Purpose OxLint Fast Rust-based JavaScript/TypeScript linting oxfmt Rust-based code formatting TypeScript strict mode Type safety across all frontend code husky + lint-staged Pre-commit hooks
Tool Purpose PostHog Product analytics and event tracking OpenTelemetry Distributed tracing (Django instrumented) Scout APM Application performance monitoring
# Clone the repository
git clone https://github.com/makeplane/plane.git && cd plane
# Run setup (copies .env, generates secret key, installs deps)
./setup.sh
# Start infrastructure (PostgreSQL, Valkey, RabbitMQ, MinIO)
docker compose -f docker-compose-local.yml up -d
# Start all apps in development
pnpm dev
Task Command Start all apps pnpm devBuild all turbo buildLint turbo check:lintFormat turbo check:formatType check turbo check:typesRun API tests cd apps/api && pytestDB migrations cd apps/api && python manage.py migrateCreate migration cd apps/api && python manage.py makemigrations