Learn from OSS
Plane

How Plane Is Built

Repository structure, build system, dependencies, deployment pipeline, and developer experience

How Plane Is Built

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.

Repository Structure

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)

The 6 Applications

AppTechnologyPurpose
webReact 18 + React Router 7 + ViteMain user-facing application (1,482 TSX files)
adminReact 18 + React Router 7 + ViteInstance administration (/god-mode/)
spaceReact 18 + React Router 7 + Vite (SSR)Public-facing project views (shareable links)
apiDjango 4.2.29 + DRF 3.15.2REST API, business logic, database management
liveNode.js + Hocuspocus 2.15.2Real-time collaborative editing WebSocket server
proxyCaddy 2.10Reverse proxy with automatic HTTPS

The 16 Shared Packages

PackagePurpose
@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.

Build System

Frontend Build Pipeline

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.

Backend (Django)

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 Map

Frontend Dependencies (Key Libraries)

DependencyVersionPurpose
React18.3.1UI framework
React Router7.12.0Client + server routing
MobX6.12.0Fine-grained reactive state management
SWR2.2.4Data fetching with stale-while-revalidate caching
Tailwind CSS4.1.17Utility-first styling
Tiptap2.22.3Rich text editor (ProseMirror-based)
Yjs13.6.20CRDT library for real-time collaboration
Vite7.3.1Build tool and dev server
Axios1.13.5HTTP client for API calls
Recharts^2.12.7Charts and data visualization
Lucide React0.469.0Icon set
Headless UI^1.7.19Accessible UI primitives
TanStack React Table^8.21.3Table component
React Hook Form7.51.5Form management
date-fns^4.1.0Date utility library

Backend Dependencies (Key Libraries)

DependencyVersionPurpose
Django4.2.29Web framework (LTS)
DRF3.15.2REST API framework
Celery5.4.0Distributed task queue
django-celery-beat2.6.0Periodic task scheduler
psycopg3.3.0PostgreSQL 3 driver
redis5.0.4Redis/Valkey client
django-redis5.4.0Django cache backend
channels4.1.0ASGI support
gunicorn23.0.0Production WSGI/ASGI server
uvicorn0.29.0ASGI server
boto31.34.96AWS S3 / MinIO integration
openai1.63.2AI features
drf-spectacular0.28.0OpenAPI/Swagger documentation
nh3(latest)HTML sanitizer (Rust-based)
posthog3.5.0Product analytics

Infrastructure Dependencies

ServiceVersionPurpose
PostgreSQL15.7-alpinePrimary database
Valkey7.2.11-alpineCache + session store (Redis-compatible)
RabbitMQ3.13.6-managementCelery message broker (AMQP)
MinIOlatestS3-compatible object storage (self-hosted)
Caddy2.10Reverse proxy with automatic HTTPS
Nginx1.27/1.29-alpineStatic frontend serving inside Docker

Deployment

Docker Compose (Primary — 13 Services)

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)

Deployment Options

StrategyTargetComplexity
Docker Compose (CLI)Single serverLow — one-line install script
KubernetesK8s clusterHigh — community-maintained manifests
All-in-OneSingle containerLowest — single Docker image with Supervisor
Docker SwarmMulti-nodeMedium — swarm.sh script

Quick Install

# One-line self-hosted install
curl -fsSL https://raw.githubusercontent.com/makeplane/plane/master/deployments/cli/community/install.sh | bash

Quality Assurance

Testing

LayerToolScope
Backendpytest 9.0.2Unit, contract, and smoke tests
FrontendVitestPackage-level unit tests
VisualStorybook + ChromaticComponent visual regression
CodemodsVitestMigration script testing

Code Quality

ToolPurpose
OxLintFast Rust-based JavaScript/TypeScript linting
oxfmtRust-based code formatting
TypeScript strict modeType safety across all frontend code
husky + lint-stagedPre-commit hooks

Monitoring in Production

ToolPurpose
PostHogProduct analytics and event tracking
OpenTelemetryDistributed tracing (Django instrumented)
Scout APMApplication performance monitoring

Developer Experience

Getting Started

# 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

Key Developer Commands

TaskCommand
Start all appspnpm dev
Build allturbo build
Lintturbo check:lint
Formatturbo check:format
Type checkturbo check:types
Run API testscd apps/api && pytest
DB migrationscd apps/api && python manage.py migrate
Create migrationcd apps/api && python manage.py makemigrations

What's Next