How to Contribute to the makeplane/plane Project: A Complete Developer's Guide
To contribute to makeplane/plane, clone the monorepo, run ./setup.sh to generate your environment files, start the Docker Compose stack for PostgreSQL and Redis, then launch the frontend with pnpm dev.
Plane is a full‑stack, open‑source project‑management platform built as a monorepo that combines a Django REST API backend and a React/TypeScript frontend. Whether you are fixing bugs or adding features, understanding how to contribute to the makeplane/plane project requires familiarity with its container‑first development workflow and TurboRepo‑powered package structure. This guide walks you through the repository layout, local setup, coding standards, and submission process based on the official source code.
Understanding the Repository Architecture
Plane uses a monorepo structure orchestrated by TurboRepo and pnpm workspaces to coordinate multiple packages and applications.
Backend: Django REST Framework
The API lives under apps/api/ and follows Django conventions. Key entry points include:
apps/api/plane/urls.py– Central URL routing for all API endpoints.apps/api/plane/views.py– ViewSets and API views handling business logic.apps/api/plane/models/– Django ORM models for PostgreSQL persistence.
Frontend: React with Vite
The user interface is split into two Vite applications:
apps/web/– The main project management UI (runs on port 3000).apps/admin/– Administrative dashboard (runs on port 3001).packages/ui/– Shared component library imported by both frontends.
Shared Packages
Reusable code lives in packages/*, including:
packages/logger– Unified logging utilities.packages/decorators– TypeScript and Python decorators.packages/ui– React component library exported viapackages/ui/index.ts.
Setting Up Your Local Development Environment
Development is container‑first, using Docker Compose to orchestrate PostgreSQL, Redis, the API server, and the frontend applications.
1. Clone and Prepare
git clone https://github.com/makeplane/plane.git
cd plane
chmod +x setup.sh
./setup.sh
The setup.sh script generates a .env file from .env.example, preparing the configuration for Docker and the application services.
2. Start Backend Services
docker compose -f docker-compose-local.yml up
This command spins up PostgreSQL, Redis, and the Django API server. The backend API will be available once the containers reach a healthy state.
3. Launch Frontend Applications
pnpm dev
This TurboRepo command starts both apps/web (port 3000) and apps/admin (port 3001) simultaneously, hot‑reloading on file changes.
Making Changes to the Codebase
Adding a New API Endpoint (Backend)
To create a new REST endpoint, define a view in apps/api/plane/views.py and register it in apps/api/plane/urls.py.
# apps/api/plane/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class ProjectStatsView(APIView):
def get(self, request):
return Response({"total": 0, "active": 0}, status=status.HTTP_200_OK)
# apps/api/plane/urls.py
from django.urls import path
from .views import ProjectStatsView
urlpatterns = [
# ... existing routes ...
path("projects/stats/", ProjectStatsView.as_view(), name="project-stats"),
]
Adding a Shared UI Component (Frontend)
Components shared across apps/web and apps/admin should be added to the packages/ui workspace.
// packages/ui/src/components/ProjectCard.tsx
import React from "react";
export const ProjectCard: React.FC<{ title: string }> = ({ title }) => (
<div className="project-card">{title}</div>
);
// packages/ui/index.ts
export * from "./components/ProjectCard";
Consuming Backend APIs in the Frontend
Use the internal API client to communicate with the Django backend:
// apps/web/src/pages/ProjectDashboard.tsx
import React, { useEffect, useState } from "react";
import { api } from "@plane/ui";
export const ProjectDashboard = () => {
const [stats, setStats] = useState({ total: 0, active: 0 });
useEffect(() => {
api.get("/api/projects/stats/").then((res) => setStats(res.data));
}, []);
return (
<div>
<h1>Projects: {stats.total}</h1>
<p>Active: {stats.active}</p>
</div>
);
};
Testing Your Changes
The project requires tests for both layers before submission.
Backend Tests (pytest‑django)
Run the Django test suite inside Docker:
docker compose -f docker-compose-test.yml up --build --abort-on-container-exit --exit-code-from api-tests
All new features must include unit tests using the @pytest.mark.django_db decorator, following the patterns in apps/api/tests/.
Frontend Tests (Vitest)
Execute the frontend test suite with pnpm:
pnpm test
Configuration resides in apps/web/vitest.config.ts and apps/admin/vitest.config.ts.
Coding Standards and Guidelines
Adhering to the project's linting and formatting rules ensures CI/CD pipelines pass without manual intervention.
Linting and Formatting
- OxLint: Configured via
.oxlintrc.jsonfor fast JavaScript/TypeScript linting. - oxfmt: Configured via
.oxfmtrc.jsonfor consistent code formatting. - Python: Follow Django best practices; use type hints where appropriate.
Dependency Management
When importing internal packages, always use the workspace protocol:
{
"dependencies": {
"@plane/ui": "workspace:*"
}
}
This ensures consistency across the monorepo as defined in pnpm-workspace.yaml.
Summary
- Clone the repository and run
./setup.shto initialize environment variables. - Orchestrate backend services with
docker compose -f docker-compose-local.yml up. - Develop frontends concurrently using
pnpm dev(TurboRepo). - Modify backend code in
apps/api/plane/and frontend code inapps/web/orpackages/ui/. - Test Python changes with
docker-compose-test.ymland TypeScript changes withpnpm test. - Submit pull requests following the template and guidelines in
CONTRIBUTING.md.
Frequently Asked Questions
Do I need to install Python and Node.js locally to contribute?
No. While you can install them locally, the recommended workflow uses Docker Compose for the backend and pnpm for the frontend. The setup.sh script and Docker containers handle all runtime dependencies, making contribution possible with only Git, Docker, and pnpm installed on your machine.
Where are the API routes defined in the Django backend?
API routing is centralized in apps/api/plane/urls.py. This file imports view classes from apps/api/plane/views.py and maps them to URL patterns. When adding new endpoints, you must register the view class in this file for the route to become available.
How do I add a component that both the web and admin apps can use?
Create the component in packages/ui/src/components/ and export it from packages/ui/index.ts. Both apps/web and apps/admin import from @plane/ui, so changes to the shared package automatically propagate to both applications when running pnpm dev.
What testing is required before submitting a pull request?
All new backend features must include pytest‑django unit tests using the @pytest.mark.django_db decorator. Frontend changes should pass the existing Vitest suite run via pnpm test. The CI pipelines in .github/workflows/ will automatically lint, type‑check, and run these tests on your pull request.
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 →