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:

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 via packages/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.json for fast JavaScript/TypeScript linting.
  • oxfmt: Configured via .oxfmtrc.json for 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.sh to 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 in apps/web/ or packages/ui/.
  • Test Python changes with docker-compose-test.yml and TypeScript changes with pnpm 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:

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 →