What Is the Purpose of the `packages` Directory in makeplane/plane?
The packages directory houses independently versioned npm modules that form the core of Plane's monorepo architecture, enabling modular code reuse, isolated build pipelines, and clear dependency management across the web, admin, and API applications.
The packages directory serves as the architectural foundation of the Plane repository, organizing the codebase into discrete, reusable modules. As an open-source project management platform, Plane uses this directory to share functionality between its frontend applications, backend services, and shared libraries. Understanding the purpose of the packages directory in makeplane/plane is essential for navigating the codebase, contributing effectively, or extending the platform with new features.
Why Plane Uses a Monorebo Architecture
Plane adopts a monorepo structure to solve complexity at scale. Splitting the codebase into the packages directory delivers six critical advantages that keep the project maintainable and performant.
Modular Code Reuse
Each package isolates a well-defined concern—ranging from UI utilities to shared state management—preventing code duplication across applications. For example, @plane/shared-state encapsulates MobX stores that synchronize workspace data between components. This package lives at packages/shared-state/package.json and exports a stable API surface that multiple applications consume without copying implementation details.
Independent Build Pipelines
Packages build separately using tsdown, a fast TypeScript compiler configured in files like packages/logger/tsdown.config.ts. This isolation enables selective rebuilding during CI/CD, so changing the logger does not trigger a full rebuild of the editor or UI components. Independent pipelines also allow individual packages to be published to npm for external consumption.
Workspace Dependency Management
Internal packages reference each other via the "workspace:*" protocol, letting pnpm resolve them locally without publishing to a registry. In packages/shared-state/package.json, you will find dependencies declared like "@plane/utils": "workspace:*", which links to the local utility package. This creates a clear, explicit dependency graph that prevents circular dependencies and version mismatches.
Consistent Tooling and Configuration
All packages inherit shared TypeScript configurations, linting rules, and formatting standards defined in the root pnpm-workspace.yaml. This ensures uniform code quality across @plane/editor, @plane/i18n, and other modules, regardless of which team maintains them.
Incremental Testing
Unit tests target specific packages rather than the entire repository. You can run pnpm turbo run test --filter=@plane/logger to validate only the logger package, reducing CI times and providing faster feedback during development.
Feature Flagging and Scalability
Packages like @plane/editor or @plane/decorators can be swapped out or lazy-loaded independently. This supports progressive enhancement, A/B testing, and gradual migrations without affecting the rest of the application.
Key Packages in the Directory
The packages directory contains dozens of specialized modules. These are the primary ones powering Plane's functionality:
@plane/shared-state(packages/shared-state): MobX-based state management for workspaces and projects.@plane/logger(packages/logger): Structured logging utilities with Express middleware support.@plane/utils(packages/utils): Common helpers likeorderWorkspacesListfor data transformation.@plane/editor(packages/editor): Rich-text editing components and prose-mirror integrations.@plane/i18n(packages/i18n): Internationalization providers and translation utilities.@plane/constants(packages/constants): Static configuration values for themes and application settings.@plane/decorators(packages/decorators): TypeScript decorators for API endpoint definitions and validation.
How to Import and Use Plane Packages
Plane packages follow standard npm import patterns despite being internal. Here are practical implementations drawn from the source code.
Importing Utilities from @plane/utils
Access workspace utilities directly from the source or compiled distribution:
// src/components/WorkspaceSelector.tsx
import { orderWorkspacesList } from "@plane/utils/src/workspace";
const sortedWorkspaces = orderWorkspacesList(workspaces);
Source: packages/utils/src/workspace.ts
Consuming Shared State with MobX
The @plane/shared-state package exports reactive stores that components observe:
import { useEffect } from "react";
import { workspaceStore } from "@plane/shared-state";
export const WorkspaceList = () => {
useEffect(() => {
workspaceStore.fetchAll();
}, []);
return (
<ul>
{workspaceStore.list.map(ws => (
<li key={ws.id}>{ws.name}</li>
))}
</ul>
);
};
Source: Built from packages/shared-state and exposed via dist/index.js.
Adding Logger Middleware
The @plane/logger package provides ready-to-use Express middleware defined in packages/logger/src/middleware.ts:
import express from "express";
import { loggerMiddleware } from "@plane/logger";
const app = express();
app.use(loggerMiddleware());
app.get("/", (req, res) => res.send("Hello"));
Source: packages/logger/src/middleware.ts
Summary
The packages directory in makeplane/plane organizes the codebase into self-contained, reusable npm modules that drive the platform's monorepo architecture. Key takeaways include:
- Modular isolation: Each package handles a specific concern like state management (
@plane/shared-state), logging (@plane/logger), or text editing (@plane/editor). - Workspace linking: Dependencies use
"workspace:*"protocol for local resolution without registry publishing. - Fast builds: Tools like
tsdowninpackages/logger/tsdown.config.tsenable selective compilation and incremental testing. - Clear boundaries: File paths like
packages/utils/src/workspace.tsandpackages/constants/src/workspace.tsdemonstrate the strict separation of utilities and configuration data.
Frequently Asked Questions
What build tool does Plane use for packages in the packages directory?
Plane uses tsdown to compile TypeScript packages. Each package contains its own tsdown.config.ts file (visible in packages/logger/tsdown.config.ts) that defines entry points, output formats, and compilation targets. This allows packages to build in parallel and cache results for faster CI/CD pipelines.
How do packages in makeplane/plane reference each other?
Packages reference internal dependencies using the workspace protocol ("workspace:*") in their package.json files. For example, packages/shared-state/package.json declares "@plane/utils": "workspace:*" to import the local utility package. Pnpm resolves these references directly from the monorepo without requiring npm registry publishing.
Can I use Plane's packages outside the main application?
Yes. Because each package in the packages directory is an independently versioned npm module with its own package.json and build configuration, you can theoretically publish them to a registry or import them into external projects. However, they are optimized for Plane's internal architecture, particularly the MobX state patterns in @plane/shared-state and the Tailwind configurations in @plane/tailwind-config.
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 →