Learn from OSS
Plane

How Plane Is Built

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

How Plane Is Built

This page covers the practical side of Plane's engineering: how the repository is organized, how the build system works, what dependencies are used, and how the product gets deployed.

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