# How to Contribute to the makeplane/plane Project: A Complete Developer's Guide

> Learn how to contribute to the makeplane/plane project. Follow this developer's guide to clone the repo, set up your environment, and launch the application.

- Repository: [Plane/plane](https://github.com/makeplane/plane)
- Tags: how-to-guide
- Published: 2026-06-19

---

**To contribute to makeplane/plane, clone the monorepo, run [`./setup.sh`](https://github.com/makeplane/plane/blob/main/./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`](https://github.com/makeplane/plane/blob/main/apps/api/plane/urls.py)** – Central URL routing for all API endpoints.
- **[`apps/api/plane/views.py`](https://github.com/makeplane/plane/blob/main/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 via [`packages/ui/index.ts`](https://github.com/makeplane/plane/blob/main/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

```bash
git clone https://github.com/makeplane/plane.git
cd plane
chmod +x setup.sh
./setup.sh

```

The [`setup.sh`](https://github.com/makeplane/plane/blob/main/setup.sh) script generates a `.env` file from `.env.example`, preparing the configuration for Docker and the application services.

### 2. Start Backend Services

```bash
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

```bash
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`](https://github.com/makeplane/plane/blob/main/apps/api/plane/views.py) and register it in [`apps/api/plane/urls.py`](https://github.com/makeplane/plane/blob/main/apps/api/plane/urls.py).

```python

# 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.

```tsx
// 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:

```tsx
// 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:

```bash
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:

```bash
pnpm test

```

Configuration resides in [`apps/web/vitest.config.ts`](https://github.com/makeplane/plane/blob/main/apps/web/vitest.config.ts) and [`apps/admin/vitest.config.ts`](https://github.com/makeplane/plane/blob/main/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`](https://github.com/makeplane/plane/blob/main/.oxlintrc.json) for fast JavaScript/TypeScript linting.
- **oxfmt**: Configured via [`.oxfmtrc.json`](https://github.com/makeplane/plane/blob/main/.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:

```json
{
  "dependencies": {
    "@plane/ui": "workspace:*"
  }
}

```

This ensures consistency across the monorepo as defined in [`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml).

## Summary

- **Clone** the repository and run [`./setup.sh`](https://github.com/makeplane/plane/blob/main/./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`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml) and TypeScript changes with `pnpm test`.
- **Submit** pull requests following the template and guidelines in [`CONTRIBUTING.md`](https://github.com/makeplane/plane/blob/main/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`](https://github.com/makeplane/plane/blob/main/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`](https://github.com/makeplane/plane/blob/main/apps/api/plane/urls.py). This file imports view classes from [`apps/api/plane/views.py`](https://github.com/makeplane/plane/blob/main/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`](https://github.com/makeplane/plane/blob/main/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.