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:

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. See packages/utils/src/workspace.ts for workspace-specific utilities.
  • @plane/constants: Static configuration values including themes, SWR settings, and sidebar layout indices. Reference packages/constants/src/themes.ts for theme definitions.

UI Components and State Management

User interface consistency derives from:

Infrastructure and Tooling

Supporting packages handle cross-cutting concerns:

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) and packages/ (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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →