Exploring the makeplane/plane Packages and Modules: A Complete Monorepo Guide
Yes, Plane is organized as a PNPM monorepo containing fourteen distinct shared packages under packages/ and five separate applications under apps/, each with isolated responsibilities and their own package.json manifests.
The makeplane/plane repository organizes its codebase into separate modules and packages using a modular monorepo architecture. This structure enables code sharing across the web client, admin console, and backend while maintaining clear boundaries between UI components, business logic, and data models. Understanding these distinct packages is essential for contributing to or extending the Plane codebase.
Monorepo Architecture Overview
Plane uses a PNPM workspace defined in pnpm-workspace.yaml at the repository root. This configuration treats every directory under packages/* and apps/* as a distinct module with its own build pipeline, dependencies, and TypeScript configuration. The workspace protocol (workspace:*) allows seamless cross-package imports without publishing to npm, ensuring that changes in shared libraries immediately propagate to consuming applications.
Shared Packages Under packages/
The fourteen utility libraries provide specific capabilities that multiple applications can compose. Each package publishes under the @plane npm scope and maintains its source code in a dedicated subdirectory.
UI and Presentation Layer
@plane/ui houses reusable React components such as buttons, dialogs, and tables. The source resides in packages/ui/src/components/, with the main entry point defined in packages/ui/package.json.
@plane/propel supplies low-level UI primitives for interactive elements including pop-overs, tooltips, and dialogs. Its manifest is located at packages/propel/package.json.
@plane/editor implements the rich-text editor component used for work-item descriptions and pages. This heavy-duty package encapsulates complex editing logic that both the web and admin apps consume.
@plane/tailwind-config centralizes Tailwind CSS configuration. Located at packages/tailwind-config/tailwind.config.ts, it provides a single source of truth for styling variables across all UI packages.
State Management and Business Logic
@plane/shared-state contains MobX stores that manage client-side state for entities like workspaces, users, and themes. Key files such as packages/shared-state/src/store/workspace.store.ts define observable state that React components subscribe to.
@plane/hooks exports custom React hooks that encapsulate business logic. For example, useWorkspace and useIssue reside in packages/hooks/src/ and provide typed interfaces for data fetching and state derivation.
@plane/services offers thin wrappers around API calls for authentication, work-item CRUD operations, and analytics. Service classes like issueService are defined in packages/services/src/issue.service.ts.
Infrastructure and Utilities
@plane/types serves as the central TypeScript definition repository. It exports interfaces for issues, cycles, modules, and pages from packages/types/src/, ensuring type consistency across the entire stack.
@plane/utils provides shared helper functions for date formatting, color utilities, and UUID generation. Source files live in packages/utils/src/.
@plane/constants stores project-wide constant values including status codes, default settings, and theme color palettes in packages/constants/src/.
@plane/i18n manages internationalization data and translation helpers. JSON translation files and formatting utilities reside in packages/i18n/src/.
@plane/logger wraps console logging with optional remote reporting capabilities, defined in packages/logger/src/.
Build and Developer Tools
@plane/typescript-config shares TypeScript compiler options via packages/typescript-config/package.json. Every other package extends this base configuration to ensure consistent tsconfig settings.
@plane/codemods houses scripts for automated code migrations, such as updating deprecated APIs across the codebase.
@plane/decorators provides TypeScript decorators—including @observable—that add behavioral metadata to classes, located in packages/decorators/src/.
Application Entry Points
In addition to shared libraries, Plane maintains five distinct applications under apps/ that serve as runtime entry points:
web: The primary client-side Single Page Application (SPA) served atlocalhost:3000. Its manifest isapps/web/package.json.admin: An administrative console for managing instance settings and user permissions.api: The Django-based backend exposing REST and GraphQL endpoints. Despite being Python-driven, it includes apackage.jsonfor workspace consistency.live: A real-time collaboration server handling live cursors and user presence via WebSockets.space: An optional micro-frontend designed to be mounted separately from the mainwebapplication.
Each app imports from the @plane/* packages using standard ES module syntax, treating shared code as external dependencies resolved through the PNPM workspace.
Practical Usage Examples
Importing UI Components from @plane/ui
Components import directly from the package without relative path traversal:
import { Button } from '@plane/ui';
export const SaveButton = () => (
<Button
variant="primary"
onClick={() => console.log('Saved!')}
>
Save
</Button>
);
Source reference: packages/ui/src/components/button.tsx
Accessing API Services via @plane/services
Service classes abstract HTTP client details behind typed methods:
import { issueService } from '@plane/services';
async function createIssue(title: string, description: string) {
const payload = { title, description };
const response = await issueService.create(payload);
return response.data;
}
Source reference: packages/services/src/issue.service.ts
Reading Global State from @plane/shared-state
MobX stores provide reactive state accessible outside React components:
import { workspaceStore } from '@plane/shared-state';
function getCurrentWorkspaceName() {
return workspaceStore.currentWorkspace?.name ?? 'Unnamed Workspace';
}
Source reference: packages/shared-state/src/store/workspace.store.ts
Using Custom Hooks from @plane/hooks
Data-fetching logic extracts into reusable hooks:
import { useIssues } from '@plane/hooks';
export const IssueList = () => {
const { issues, loading, error } = useIssues();
if (loading) return <p>Loading…</p>;
if (error) return <p>Error loading issues.</p>;
return (
<ul>
{issues.map(issue => (
<li key={issue.id}>{issue.title}</li>
))}
</ul>
);
};
Source reference: packages/hooks/src/useIssues.ts
Summary
- Plane organizes code into fourteen shared packages under
packages/and five applications underapps/, forming a PNPM monorepo. - Each module maintains independent versioning, TypeScript configuration, and build scripts defined in its respective
package.json. - The
pnpm-workspace.yamlfile enables cross-package imports via theworkspace:*protocol, eliminating the need for manual linking or publishing during development. - Presentation logic separates into
@plane/ui,@plane/propel, and@plane/editor, while state management concentrates in@plane/shared-stateand@plane/hooks. - Type safety is enforced centrally through
@plane/types, ensuring consistent data models across the Python backend and TypeScript frontend.
Frequently Asked Questions
What is the difference between packages and apps in the Plane monorepo?
Packages under packages/ are library modules that export reusable code such as React components, TypeScript types, or utility functions. Apps under apps/ are executable entry points that bundle these packages into deployable services, such as the Next.js web client or the Django api server. Apps consume packages, but packages never depend on apps.
How do I import functionality from one Plane package into another?
Use standard ES module imports with the @plane scope. The PNPM workspace automatically resolves these imports to the local source code. For example, import { Button } from '@plane/ui' resolves to packages/ui/src/ during development, with the relationship defined in pnpm-workspace.yaml at the repository root.
Which package contains the React UI components?
The @plane/ui package contains high-level React components including buttons, dialogs, and tables. For lower-level interactive primitives like tooltips and pop-overs, use @plane/propel. Both packages are located in packages/ui/ and packages/propel/ respectively, with their exports defined in their package.json files.
Where are the TypeScript type definitions stored in Plane?
All shared TypeScript interfaces and type aliases reside in @plane/types, located at packages/types/. Centralizing types in this module prevents circular dependencies and ensures that entities like issues, cycles, and workspaces maintain consistent shapes across the frontend stores, API client services, and backend contracts.
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 →