11 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Plane is an open-source project management tool (alternative to Jira/Linear) built as a monorepo with a Django REST API backend and multiple Next.js/React Router frontend applications. The codebase uses pnpm workspaces with Turbo for build orchestration.
Architecture
Monorepo Structure
apps/
├── web/ # Next.js 14 - Main application (port 3000)
├── admin/ # React Router v7 - Admin interface (port 3001)
├── space/ # Next.js 14 - Public project viewer (port 3002)
├── live/ # Node.js - Real-time collaboration server (HocusPocus)
└── api/ # Django 4.2 - REST API (port 8000, Python, not in pnpm workspace)
packages/
├── @plane/types # TypeScript type definitions
├── @plane/services # API client layer
├── @plane/ui # Shared React components
├── @plane/propel # Additional design system components
├── @plane/hooks # Shared React hooks
├── @plane/shared-state # MobX stores
├── @plane/constants # Application constants
├── @plane/utils # Utility functions
├── @plane/i18n # Internationalization (21+ languages)
└── @plane/editor # TipTap rich text editor
Frontend Applications
apps/web/ - Main Next.js application
- Next.js 14 App Router with standalone build
- MobX for state management, SWR for data fetching
- Tailwind CSS styling
- Admin panel accessible at
/god-mode(proxied from admin app) - Key features: Issues, Cycles, Modules, Views, Pages, Analytics
apps/admin/ - Admin interface (recently migrated to React Router v7)
- IMPORTANT: Migrated from Next.js to React Router v7 + Vite (WEB-5040)
- File-based routing with React Router v7
- Vite for faster builds vs Next.js
- Express adapter for optional SSR (disabled by default)
- Compatibility shims for
next/image,next/link,next/navigation
apps/space/ - Public project viewer
- Next.js 14 for read-only project sharing
- Only app using Material-UI (not shared with other apps)
- Simpler feature set focused on viewing
apps/live/ - Real-time collaboration
- Node.js Express + WebSocket server
- HocusPocus 2.15.2 for CRDT-based collaborative editing
- Yjs for document synchronization
- Redis extension for distributed architecture
Backend (Django API)
apps/api/ - Django REST API
- Django 4.2.25 + DRF 3.15.2
- PostgreSQL v14 (primary database)
- Redis v6.2.7 (caching)
- Celery for background tasks
- drf-spectacular for OpenAPI documentation
Key Django modules:
plane/db/models/- Database models (~33 files: issue, cycle, module, project, workspace, etc.)plane/api/views/- REST endpoints (class-based views)plane/app/serializers/- Request/response schemasplane/settings/- Environment-based settings (base, local, production, test)plane/bgtasks/- Celery tasks for webhooks, notifications
Django settings pattern:
- Environment variable:
DJANGO_SETTINGS_MODULE=plane.settings.{local|production|test} - Modular settings in
plane/settings/: base, local, production, test, common, storage, redis, openapi, mongo
Development Commands
Initial Setup
# Clone and setup
git clone https://github.com/makeplane/plane.git
cd plane
chmod +x setup.sh
./setup.sh # Copies .env.example files, generates SECRET_KEY, installs dependencies
# Start backend services (PostgreSQL, Redis, MinIO, Django API)
docker compose -f docker-compose-local.yml up
# Start all frontend apps in dev mode (concurrency: 18)
pnpm dev
Access points:
- Web: http://localhost:3000
- Admin: http://localhost:3001/god-mode (or via Web's
/god-mode) - Space: http://localhost:3002
- API: http://localhost:8000
First-time setup:
- Open http://localhost:3001/god-mode/ and register as instance admin
- Use same credentials to log in at http://localhost:3000
Build Commands
# Build all packages/apps (respects dependency graph)
pnpm build
# Development mode (watch mode, no cache)
pnpm dev
# Production start
pnpm start
Code Quality
# Run all checks (format, lint, types)
pnpm check
# Individual checks
pnpm check:format # Prettier formatting check
pnpm check:lint # ESLint check
pnpm check:types # TypeScript type checking
# Auto-fix
pnpm fix # Fix format + lint
pnpm fix:format # Auto-format with Prettier
pnpm fix:lint # Auto-fix ESLint issues
Linting tolerances:
- apps/web: Max 821 warnings
- apps/admin: Max 19 warnings
- apps/space: Max 28 warnings
Testing
Frontend tests:
pnpm test # Run tests in all packages/apps
Django API tests:
cd apps/api
# Using the test runner script
python run_tests.py -u # Unit tests only
python run_tests.py -c # Contract tests (API endpoints)
python run_tests.py -s # Smoke tests
python run_tests.py -o # With coverage report
python run_tests.py -p # Parallel execution
python run_tests.py -v # Verbose
# Direct pytest
pytest -m unit # Unit tests
pytest -m contract # Contract tests
pytest -m smoke # Smoke tests
pytest --cov=plane --cov-report=html # Coverage report (target: 90%)
Test markers:
@pytest.mark.unit- Unit tests (models, serializers, utils)@pytest.mark.contract- API endpoint tests@pytest.mark.smoke- Critical functionality@pytest.mark.slow- Long-running tests
Pytest flags:
--reuse-db- Reuse test database (faster, default in pytest.ini)--nomigrations- Skip migrations (faster, default in pytest.ini)-n auto- Parallel execution with pytest-xdist
Package Management
# Add dependency to specific package
cd packages/types
pnpm add <package>
# Add dependency to specific app
cd apps/web
pnpm add <package>
# Install all dependencies (from root)
pnpm install
# Clean all build artifacts
pnpm clean # Removes .turbo, .next, node_modules, dist
State Management & Data Flow
State architecture:
- Global State: MobX stores in
@plane/shared-state(reactive, observable) - Server State: SWR for API caching with automatic revalidation
- Local State: React hooks (
useState,useReducer)
API communication:
- Typed API client:
@plane/services(Axios-based) - Authentication: Token-based via
X-API-Keyheader - Real-time: WebSocket via HocusPocus in
apps/live
Type flow:
- Backend models (Django) → OpenAPI spec (drf-spectacular)
- TypeScript types in
@plane/types - API services in
@plane/servicesconsume types - Frontend apps consume typed services
Key Technical Details
Turbo Build System
- Cache strategy: Build, test, and build-storybook tasks are cached
- No cache: Dev, linting, formatting, type-checking (side effects)
- Dependency graph: Tasks with
^buildwait for dependencies to build first - Global env vars: All
NEXT_PUBLIC_*vars passed to all tasks (see turbo.json)
Internationalization (i18n)
Located in packages/i18n/src/locales/:
- Supports 21+ languages (en, fr, de, es, zh, ja, pt, etc.)
- Uses IntlMessageFormat for dynamic content
- Nested JSON structure for organization
- Example:
{count, plural, one {Work item} other {Work items}}
Adding translations:
- Update
packages/i18n/src/types/language.tswith new language code - Update
packages/i18n/src/constants/language.tswith language option - Create
locales/<lang>/translations.jsonwith all keys - Update import logic in language store
Admin App Migration (React Router v7)
The admin app was recently migrated from Next.js to React Router v7 (PR WEB-5040):
- Rationale: Faster builds with Vite vs Next.js
- Compatibility layer: Shims for
next/image,next/link,next/navigation - Build: Static SPA by default (SSR disabled)
- Routing: File-based routing maintained for similar DX to Next.js
- When working on admin, remember it uses Vite, not Next.js tooling
Edition Split (CE/EE)
Code organized by edition in apps (web, admin, space):
core/- Shared codece/- Community Edition featuresee/- Enterprise Edition features (requires license)
Docker & Deployment
Each app has two Dockerfiles:
Dockerfile.<app>- Multi-stage production buildDockerfile.dev- Development with hot reload
Docker Compose:
docker-compose-local.yml- Local developmentdocker-compose.yml- Production
Dependencies in containers:
- PostgreSQL v14
- Redis v6.2.7
- MinIO (S3-compatible storage)
- RabbitMQ (message queue for Celery)
Common Patterns
Adding a New Frontend Component
- Create in appropriate package:
- Shared UI →
packages/ui/src/ - App-specific →
apps/{web|admin|space}/core/components/
- Shared UI →
- Export from package index if shared
- Use Tailwind CSS for styling
- Follow existing naming conventions (PascalCase for components)
Adding a New API Endpoint
- Create/update model in
apps/api/plane/db/models/ - Create migration:
python manage.py makemigrations - Add serializer in
apps/api/plane/app/serializers/ - Add view in
apps/api/plane/api/views/ - Register URL in
apps/api/plane/app/urls/ - Add OpenAPI docs via docstrings (drf-spectacular)
- Update types in
packages/types/ - Update services in
packages/services/ - Write tests (unit + contract)
Adding a New Package
- Create directory in
packages/ - Add
package.jsonwith proper name:@plane/<name> - Use
tsdownfor build (ESM/CJS dual output) - Export from
index.ts - Add to
pnpm-workspace.yaml(auto-included viapackages/*) - Reference in consuming apps:
"@plane/<name>": "workspace:*"
Pull Request Guidelines
Issue naming conventions:
- Bugs:
🐛 Bug: [description] - Features:
🚀 Feature: [description] - Improvements:
🛠️ Improvement: [description] - Docs:
📘 Docs: [description]
PR template requires:
- Type of change (bug fix, feature, improvement, refactoring, perf, docs)
- Detailed description
- Screenshots/media (if UI changes)
- Test scenarios
- References to related issues
Base branch:
- Main branch:
preview(check git status at project root) - PRs should target
previewunless specified otherwise
Pre-PR checklist:
- Tests pass (
pnpm testfor frontend,python run_tests.pyfor backend) - Linting passes (
pnpm check:lint) - Type checking passes (
pnpm check:types) - Code formatted (
pnpm fix:format)
Requirements
System requirements:
- Node.js 22+ (LTS)
- Python 3.8+
- Docker & Docker Compose
- Memory: Minimum 12 GB RAM
- ⚠️ 8 GB may cause failures during setup
Version constraints:
- PostgreSQL v14
- Redis v6.2.7
- pnpm 10.12.1 (via corepack)
Useful Resources
- Product docs: https://docs.plane.so/
- Developer docs: https://developers.plane.so/
- API docs: https://developers.plane.so/api-reference/introduction
- Discord: https://discord.com/invite/A92xrEGCge
- GitHub Issues: https://github.com/makeplane/plane/issues