# Plane Monorepo Structure Explained: A Deep Dive into the pnpm Workspace Architecture

> Explore the Plane monorepo structure, a pnpm workspace organizing apps and packages. Understand how Next.js UI, Django API, and libraries interact in this architecture.

- Repository: [Plane/plane](https://github.com/makeplane/plane)
- Tags: internals
- Published: 2026-08-23

---

**The Plane monorepo is organized as a pnpm-managed workspace divided into three top-level categories—`apps`, `packages`, and configuration files—where independent applications (Next.js web UI, Django API, Node.js live server, and Caddy proxy) consume reusable libraries for UI components, MobX state management, and domain services.**

The Plane monorepo structure follows modern open-source architecture patterns by leveraging pnpm workspaces to coordinate multiple applications and shared libraries. As implemented in the `makeplane/plane` repository, this layout enables teams to develop the web interface, backend API, and real-time collaboration services in isolation while sharing strictly-versioned utilities and TypeScript types across the entire codebase.

## Top-Level Architecture

The repository root defines the workspace boundary in **[`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml)**, which declares glob patterns for `apps/*` and `packages/*` alongside a centralized catalog of pinned external dependencies. This configuration establishes three distinct zones:

- **`apps/`** – Executable entry points including the Next.js frontend (`apps/web`), Django REST API (`apps/api`), real-time Node.js server (`apps/live`), and Caddy reverse proxy (`apps/proxy`)
- **`packages/`** – Reusable libraries published as internal packages, including React UI components, MobX stores, business services, and utility hooks
- **Configuration** – Workspace-level tooling including [`.oxlintrc.json`](https://github.com/makeplane/plane/blob/main/.oxlintrc.json) (linting rules), [`.oxfmtrc.json`](https://github.com/makeplane/plane/blob/main/.oxfmtrc.json) (formatting rules), and root [`package.json`](https://github.com/makeplane/plane/blob/main/package.json) scripts for `dev`, `build`, and `test` operations

Each package maintains its own **[`tsconfig.json`](https://github.com/makeplane/plane/blob/main/tsconfig.json)** and **[`tsdown.config.ts`](https://github.com/makeplane/plane/blob/main/tsdown.config.ts)**, allowing independent builds while inheriting shared TypeScript settings from the workspace root.

## Apps Directory: Service Entry Points

The `apps` folder contains four distinct services that constitute the complete Plane deployment stack. Each application owns its deployment lifecycle and runtime environment.

### Web Application (Next.js)

The **`apps/web`** directory houses the primary user interface built with Next.js and React. This application consumes components from `@plane/ui` and state from `@plane/shared-state` to render the project management interface. Key entry points include [`apps/web/react-router.config.ts`](https://github.com/makeplane/plane/blob/main/apps/web/react-router.config.ts) for routing configuration and standard Next.js pages for the UI surface.

### API Server (Django)

**`apps/api`** contains the Django REST API that persists workspace data and handles business logic. The WSGI entry point at **[`apps/api/plane/wsgi.py`](https://github.com/makeplane/plane/blob/main/apps/api/plane/wsgi.py)** bootstraps the Python application, exposing endpoints consumed by the web client and external integrations.

### Live Collaboration Server (Node.js)

**`apps/live`** runs a Node.js server enabling real-time features such as presence indicators and cursor synchronization. Located at [`apps/live/src/server.ts`](https://github.com/makeplane/plane/blob/main/apps/live/src/server.ts), this service imports workspace logic from `@plane/services` to validate permissions during WebSocket connections.

### Reverse Proxy (Caddy)

**`apps/proxy`** provides a Caddy-based container that routes production traffic to the appropriate backend services, handling TLS termination and load balancing between the web, API, and live servers.

## Packages Directory: Shared Libraries

The `packages` directory contains domain-specific libraries that enforce separation of concerns between presentation, state, and business logic.

### UI Components and Design System

**`packages/ui`** exports Tailwind-styled React components such as dropdowns, typography scales, and form controls. Components like [`packages/ui/src/dropdown/single-select.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/dropdown/single-select.tsx) demonstrate the design system implementation, consuming workspace themes and accessibility standards.

### State Management with MobX

**`packages/shared-state`** centralizes MobX stores that expose domain data to React components. Utilities such as [`packages/shared-state/src/utils/work-item-filters.helper.ts`](https://github.com/makeplane/plane/blob/main/packages/shared-state/src/utils/work-item-filters.helper.ts) manage complex filter state, while the main index at [`packages/shared-state/src/utils/index.ts`](https://github.com/makeplane/plane/blob/main/packages/shared-state/src/utils/index.ts) exports stores for workspace and project data.

### Business Logic Services

**`packages/services`** encapsulates domain operations including workspace CRUD, notifications, and permissions. The file **[`packages/services/src/workspace/workspace.service.ts`](https://github.com/makeplane/plane/blob/main/packages/services/src/workspace/workspace.service.ts)** defines the `WorkspaceService` class that both the web app and live server import to maintain consistent business rules.

### Utilities and Hooks

**`packages/utils`** provides general-purpose TypeScript helpers for file handling and data transformation, while **`packages/hooks`** contains React-specific logic such as [`packages/hooks/src/use-outside-click-detector.tsx`](https://github.com/makeplane/plane/blob/main/packages/hooks/src/use-outside-click-detector.tsx) for UI interactions. Additional libraries include **`packages/i18n`** for internationalization and **`packages/editor`** for TipTap-based rich-text integration.

## Working with Plane's Code: Practical Examples

The following patterns demonstrate how applications consume packages within the Plane monorepo structure.

### Importing UI Components

Import dropdown components from the shared UI library to maintain consistent design patterns:

```typescript
import { Dropdown } from "@plane/ui";

function ProjectSelector({ projects, selected, onSelect }) {
  return (
    <Dropdown
      value={selected}
      onChange={onSelect}
      options={projects.map(p => ({ value: p.id, label: p.name }))}
      buttonContent="Select project"
      placeholder="Search projects…"
    />
  );
}

```

*Source:* [`packages/ui/src/dropdown/single-select.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/dropdown/single-select.tsx)

### Accessing Shared State

Connect React components to MobX stores using the shared-state package:

```typescript
import { useWorkspaceStore } from "@plane/shared-state";

function WorkspaceHeader() {
  const { workspace } = useWorkspaceStore();
  return <h1>{workspace?.name ?? "Untitled Workspace"}</h1>;
}

```

*Source:* [`packages/shared-state/src/utils/work-item-filters.helper.ts`](https://github.com/makeplane/plane/blob/main/packages/shared-state/src/utils/work-item-filters.helper.ts)

### Calling Domain Services

Execute business logic from the services package across different runtimes:

```typescript
import { WorkspaceService } from "@plane/services";

async function createWorkspace(name: string) {
  const ws = await WorkspaceService.create({ name });
  console.log("New workspace:", ws.id);
}

```

*Source:* [`packages/services/src/workspace/workspace.service.ts`](https://github.com/makeplane/plane/blob/main/packages/services/src/workspace/workspace.service.ts)

### Using Custom React Hooks

Implement UI behaviors using shared hooks for common interaction patterns:

```typescript
import { useOutsideClickDetector } from "@plane/hooks";
import { useRef } from "react";

function Modal({ onClose }) {
  const ref = useRef<HTMLDivElement>(null);
  useOutsideClickDetector(ref, onClose, true);
  return <div ref={ref}>Modal content</div>;
}

```

*Source:* [`packages/hooks/src/use-outside-click-detector.tsx`](https://github.com/makeplane/plane/blob/main/packages/hooks/src/use-outside-click-detector.tsx)

## Summary

The Plane monorepo structure demonstrates enterprise-grade organization through strategic separation of concerns:

- **pnpm workspaces** coordinate dependencies across `apps` and `packages` via [`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml) and centralized catalog management
- **Four specialized applications** handle distinct responsibilities: Next.js for UI, Django for REST API, Node.js for real-time features, and Caddy for traffic routing
- **Seven core packages** enforce architectural boundaries between UI components (`packages/ui`), state containers (`packages/shared-state`), business services (`packages/services`), and framework-agnostic utilities (`packages/utils`)
- **Independent build configurations** in each package ([`tsdown.config.ts`](https://github.com/makeplane/plane/blob/main/tsdown.config.ts), [`tsconfig.json`](https://github.com/makeplane/plane/blob/main/tsconfig.json)) enable parallel compilation while maintaining type safety across workspace boundaries

## Frequently Asked Questions

### What package manager does the Plane monorepo use?

The Plane repository uses **pnpm** to manage dependencies and workspace linking. The [`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml) file at the repository root defines the workspace glob patterns (`apps/*`, `packages/*`) and specifies a catalog of pinned external dependencies that ensures version consistency across all applications and libraries.

### How does the Plane monorepo handle TypeScript compilation?

Each package in the Plane monorepo contains its own **[`tsconfig.json`](https://github.com/makeplane/plane/blob/main/tsconfig.json)** and **[`tsdown.config.ts`](https://github.com/makeplane/plane/blob/main/tsdown.config.ts)** files, allowing independent compilation while extending shared TypeScript configurations from the workspace root. This setup enables parallel builds during CI/CD pipelines while maintaining strict type checking across package boundaries.

### Where is the business logic located in the Plane codebase?

Domain business logic resides in **`packages/services`**, specifically in files like [`packages/services/src/workspace/workspace.service.ts`](https://github.com/makeplane/plane/blob/main/packages/services/src/workspace/workspace.service.ts). This separation ensures that both the Next.js web application and the Node.js live server consume identical business rules for workspace operations, notifications, and permissions, preventing logic duplication between frontend and backend contexts.

### What is the relationship between `apps/web` and `packages/ui`?

The **`apps/web`** Next.js application imports React components from **`packages/ui`** as a dependency (`@plane/ui`). This architectural pattern allows the UI library to evolve independently—maintaining its own versioning, testing, and build pipeline—while the web app consumes stable component releases through the pnpm workspace linking mechanism.