Plane Module and Project Organization: Inside the pnpm Monorepo Architecture
Plane organizes its codebase as a pnpm-powered monorepo that partitions runnable services into apps/ and reusable libraries into packages/, enabling strict separation of concerns while sharing TypeScript types, UI components, and state logic across a Django backend and multiple React frontends.
Plane, the open-source project management platform developed by makeplane/plane, employs a sophisticated module and project organization strategy to maintain scalability across its diverse toolchain. The repository structure supports a Python-powered REST API alongside several React applications, all unified through modern JavaScript package management and shared libraries.
Monorepo Architecture Overview
Plane adopts a monorepo structure managed by pnpm workspaces and orchestrated with Turbo. This approach consolidates the entire codebase—spanning backend APIs, frontend applications, and shared utilities—into a single version-controlled repository. The root directory divides cleanly into two primary containers: apps/ for deployable services and packages/ for importable libraries.
The build system enforces strict TypeScript standards (strict: true) across all TypeScript packages, while eslint, oxlint, and oxfmt provide uniform linting and formatting. Docker Compose configurations (docker-compose.yml and docker-compose-test.yml) further standardize development environments for the PostgreSQL, Redis, Django, and Node.js services.
The Apps Directory: Runnable Services
The apps/ directory houses six distinct applications, each serving specific user-facing or infrastructure roles.
API: Django Backend
The apps/api/ directory contains the Django and Django REST Framework (DRF) backend, exposing both REST and GraphQL endpoints. This application serves as the central data layer, handling workspace management, issue tracking, and authentication. The entry point resides at apps/api/plane/api/__init__.py, where Django application initialization and URL routing occur.
Web: Primary React SPA
apps/web/ hosts the main user interface built as a React single-page application using Vite. The entry point at apps/web/src/main.tsx bootstraps the React root, initializes routing, and wires up MobX state stores. This app consumes the majority of shared packages, importing components from @plane/ui, state management from @plane/shared-state, and type definitions from @plane/types.
Admin, Live, and Space: Specialized UIs
Three additional React applications provide targeted functionality:
apps/admin/: A dedicated administrative interface for workspace management, entry atapps/admin/src/main.tsx.apps/live/: A live-preview and real-time editing environment, entry atapps/live/src/main.tsx.apps/space/: A workspace-centric UI variant optimized for specific user workflows, entry atapps/space/src/main.tsx.
Each specialized UI reuses the core component library and state stores while routing to distinct feature sets or rendering contexts.
Proxy: Caddy Reverse Proxy
The apps/proxy/ directory contains Caddy configuration files (such as Caddyfile.ce) for production deployment. This service handles static asset delivery and reverse-proxying to the API and web services.
The Packages Directory: Shared Libraries
The packages/ directory contains fourteen reusable libraries that enforce DRY (Don't Repeat Yourself) principles across the frontend applications.
Core Types and Utilities
The foundation rests on three critical packages:
@plane/types: Central TypeScript definitions for domain entities like Workspaces, Issues, and Views. Key file:packages/types/src/workspace.ts.@plane/utils: General-purpose TypeScript helpers for date formatting, filtering, and file operations. Seepackages/utils/src/workspace.tsfor workspace-specific utilities.@plane/constants: Static configuration values including themes, SWR settings, and sidebar layout indices. Referencepackages/constants/src/themes.tsfor theme definitions.
UI Components and State Management
User interface consistency derives from:
@plane/ui: A shared React component library exporting buttons, dropdowns, and icons. The central registry atpackages/ui/src/utils/icons.tsmanages iconography across all apps.@plane/shared-state: MobX stores and state helpers that maintain client-side filter states and notifications. Complex filter logic resides inpackages/shared-state/src/utils/work-item-filters.helper.ts.@plane/hooks: Custom React hooks for data fetching and mutations, includinguseWorkspacedefined inpackages/hooks/src/useWorkspace.ts.@plane/propel: UI positioning helpers for popovers, tooltips, and drag-and-drop interactions, implemented inpackages/propel/src/utils/placement.ts.
Infrastructure and Tooling
Supporting packages handle cross-cutting concerns:
@plane/logger: Node.js middleware for structured logging and request tracing, defined inpackages/logger/src/middleware.ts.@plane/decorators: API wrappers that add error handling and authentication to REST and WebSocket handlers. Seepackages/decorators/src/rest.ts.@plane/services: Thin abstraction layers for external services like S3 and email, with S3 logic inpackages/services/src/s3.ts.@plane/editor: A rich-text markdown editor implementation with parsing logic atpackages/editor/src/editor/index.ts.@plane/i18n: Internationalization utilities and language data structures, types defined inpackages/i18n/src/types/language.ts.@plane/codemods: Automated code transformation scripts for migrations, such aspackages/codemods/remove-directives.ts.
Cross-Package Import Patterns
The module and project organization enables clean dependency graphs where applications import strictly-versioned workspace packages.
React Component Consumption
Components in the web app import shared libraries using pnpm workspace protocol:
// apps/web/src/components/WorkspaceBanner.tsx
import { Button } from '@plane/ui';
import { useWorkspace } from '@plane/hooks';
import { Workspace } from '@plane/types';
export const WorkspaceBanner = () => {
const { data: workspace } = useWorkspace();
return (
<div>
<h1>{(workspace as Workspace).name}</h1>
<Button onClick={() => console.log('clicked')}>Add Issue</Button>
</div>
);
};
Utility Function Implementation
Shared utilities consume types for type-safe operations:
// packages/utils/src/issue-helpers.ts
import { formatDate } from '@plane/utils';
import type { Issue } from '@plane/types';
export function issueDueLabel(issue: Issue): string {
return issue.due_date ? formatDate(issue.due_date) : 'No due date';
}
Backend Integration
The Django backend maintains consistency with frontend constants through shared definitions:
# apps/api/plane/views/theme.py
from constants import THEMES
from logger import get_logger
logger = get_logger(__name__)
def get_theme(request):
logger.info("Fetching theme")
return JsonResponse({"theme": THEMES['default']})
Key Configuration Files
Several files anchor the monorepo structure:
pnpm-workspace.yaml: Declares workspace packages and applications, enabling pnpm to link dependencies between local folders.apps/web/vite.config.ts: Configures the Vite build pipeline for the main frontend.docker-compose.yml: Orchestrates PostgreSQL, Redis, Django, and Node services for development parity.
Summary
- Plane employs a pnpm/Turbo monorepo splitting code into
apps/(services) andpackages/(libraries). - Apps include a Django API (
apps/api/), primary React web UI (apps/web/), specialized React apps (admin,live,space), and a Caddy proxy. - Packages provide shared React components (
@plane/ui), MobX state (@plane/shared-state), TypeScript definitions (@plane/types), and infrastructure tooling (@plane/logger,@plane/services). - Strict TypeScript and unified linting rules apply across all TypeScript packages, while Docker Compose ensures consistent backend environments.
- Cross-package imports use workspace protocols (e.g.,
@plane/utils), maintaining type safety and code reuse.
Frequently Asked Questions
What build tools does Plane use for its monorepo?
Plane uses pnpm workspaces combined with Turbo to orchestrate builds and task execution. The pnpm-workspace.yaml file defines the package boundaries, while Turbo optimizes build caching across the dependency graph. Commands like pnpm turbo run build --filter=web build specific applications with their dependency trees.
How does Plane share code between its React applications?
Plane shares code through the packages/ directory, which publishes to the @plane npm scope. Applications import shared logic using explicit package names such as @plane/ui for components, @plane/types for TypeScript definitions, and @plane/shared-state for MobX stores. This prevents duplication while allowing independent versioning of shared libraries.
Why does Plane use both Django and React in the same repository?
The monorepo structure aligns the Django REST API (apps/api/) with its React consumers (apps/web/, apps/space/, etc.) to ensure API contracts and TypeScript types remain synchronized. Shared packages like @plane/constants and @plane/types can be consumed by both Python (via stubs) and TypeScript codebases, reducing integration drift between backend and frontend.
Where is the entry point for the main Plane web interface?
The primary entry point for the web application is apps/web/src/main.tsx. This file initializes the React root component, configures the router, and injects the MobX state providers from @plane/shared-state. It serves as the Vite build target for the production SPA bundle.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →