Where to Find the Source Code for the Core Logic of Plane: A Complete Developer's Guide
The source code for the core logic of Plane resides in the Django backend under apps/api/plane, specifically within the domain models (db/models/), API serializers (app/serializers/), and view controllers (web/views.py).
Plane is an open-source project management platform structured as a mono-repository combining a Django REST API, shared TypeScript packages, and a React UI. If you are extending functionality, debugging, or integrating with Plane programmatically, locating the source code for the core logic of Plane is essential for understanding how workspaces, issues, and projects are managed. The authoritative business rules live entirely within the Python backend; frontend packages consume this API but do not implement core logic.
High-Level Backend Architecture
The makeplane/plane repository organizes its Django application under apps/api/plane. This directory contains the complete stack responsible for workspaces, projects, issues, cycles, and permissions, following a layered architecture:
- Domain Models (
apps/api/plane/db/models/) – Define database schema, relationships, and business methods. - Serializers (
apps/api/plane/app/serializers/) – Handle validation and conversion between Django models and JSON payloads. - Views (
apps/api/plane/web/views.py) – Process HTTP requests, enforce permissions, and orchestrate business rules. - URL Routing (
apps/api/plane/api/urls/) – Map REST endpoints to view functions (e.g.,apps/api/plane/api/urls/work_item.py). - Utilities (
apps/api/plane/utils/) – Provide reusable filters, pagination, and export logic. - Middleware (
apps/api/plane/middleware/) – Execute request-level authentication and logging.
The frontend packages (packages/ui, packages/editor, etc.) are React-based clients that consume the JSON API exposed by these layers.
Domain Models: The Database Layer
The heart of Plane's data logic lives in apps/api/plane/db/models/. Files such as issue.py and project.py define Django ORM models with custom save() methods, clean() validation, and manager helpers that enforce business rules.
When you create an issue, the logic in apps/api/plane/db/models/issue.py triggers auto-assignment of default statuses and updates related cycle counters. Workspace hierarchy and project ownership rules are enforced in apps/api/plane/db/models/project.py. These models ensure data integrity regardless of which client accesses the API.
Key Model Files
apps/api/plane/db/models/issue.py– Core Issue model with lifecycle hooks.apps/api/plane/db/models/project.py– Project and workspace hierarchy.apps/api/plane/license/models/instance.py– SaaS subscription and instance management.
API Layer: Serializers and Views
Incoming requests are processed by Django Rest Framework (DRF) components located in apps/api/plane/app/serializers/ and apps/api/plane/web/views.py.
Serializers in apps/api/plane/app/serializers/issue.py validate incoming JSON payloads, transforming them into Python objects before database insertion. They also serialize model instances back to JSON for API responses.
Views in apps/api/plane/web/views.py (including class-based ViewSets like IssueViewSet) orchestrate the request flow. They check permissions, instantiate the appropriate serializer, call model methods, and return formatted responses. The URL configuration in apps/api/plane/api/urls/work_item.py maps endpoints such as /api/workspaces/<id>/issues/ to these view components.
Utilities, Middleware, and Cross-Cutting Concerns
Cross-cutting concerns are modularized to keep views and models clean.
The utility layer at apps/api/plane/utils/ contains reusable components. The apps/api/plane/utils/filters/filter_backend.py file provides advanced query filtering used across list endpoints, while apps/api/plane/utils/exporters/exporter.py handles CSV and JSON data exports.
Middleware in apps/api/plane/middleware/ intercepts requests before they reach views. The apps/api/plane/middleware/api_authentication.py file specifically handles token-based API authentication, while other modules manage request logging and body-size validation.
Request Flow Through the Core Logic
When a client creates an issue via the REST API, the request traverses the following path through the source code:
- URL Resolution –
apps/api/plane/api/urls/work_item.pymatches the endpoint to theIssueViewSet. - View Handling – The view in
apps/api/plane/web/views.pyreceives the request and checks permissions. - Serialization –
apps/api/plane/app/serializers/issue.pyvalidates the incoming payload. - Model Execution – The validated data instantiates or modifies an
Issuemodel fromapps/api/plane/db/models/issue.py, triggering customsave()logic. - Utility Integration – Filter backends or export utilities from
apps/api/plane/utils/process the queryset as needed. - Response – The serializer renders the final JSON, which the view returns to the client.
This pipeline ensures that all business rules execute within the Django layer, guaranteeing consistency across web, CLI, or third-party integrations.
Practical Code Examples
Creating an Issue via the REST API
You can interact with the core logic directly using standard HTTP requests:
curl -X POST https://api.plane.so/api/workspaces/<workspace-id>/issues/ \
-H "Authorization: Bearer <your-api-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Example issue",
"description_text": "Detailed description",
"project": "<project-id>",
"priority": "high"
}'
Behind the scenes, this hits the URL configuration in apps/api/plane/api/urls/work_item.py, invokes the IssueViewSet, validates through apps/api/plane/app/serializers/issue.py, and persists via apps/api/plane/db/models/issue.py.
Direct ORM Access for Administrative Scripts
For data migrations or administrative tasks, access the core logic directly:
from plane.db.models import Issue, Project, Workspace
# Assume you have a Workspace instance already
workspace = Workspace.objects.get(id="ws_123")
project = Project.objects.get(id="prj_456", workspace=workspace)
new_issue = Issue.objects.create(
name="Programmatic issue",
description_text="Created from a script",
project=project,
priority="medium",
)
print(f"Issue created with id: {new_issue.id}")
This references apps/api/plane/db/models/issue.py and apps/api/plane/db/models/project.py directly, bypassing the HTTP layer while maintaining all model-level business rules.
Exporting Issues Using Utility Classes
The utility layer provides standardized export functionality:
from plane.utils.exporters.exporter import Exporter
from plane.db.models import Issue
issues_qs = Issue.objects.filter(workspace_id="ws_123")
csv_bytes = Exporter.export_to_csv(issues_qs)
with open("issues.csv", "wb") as f:
f.write(csv_bytes)
This utilizes the export logic defined in apps/api/plane/utils/exporters/exporter.py, ensuring consistent data formatting across the application.
Summary
- The source code for the core logic of Plane is located in the Django backend at
apps/api/plane, separate from the frontend packages. - Domain models in
apps/api/plane/db/models/encapsulate data integrity, relationships, and business methods. - Serializers in
apps/api/plane/app/serializers/and views inapps/api/plane/web/views.pyform the API contract and request handling layer. - Utilities and middleware in
apps/api/plane/utils/andapps/api/plane/middleware/handle cross-cutting concerns like filtering, exports, and authentication. - The request lifecycle consistently flows from URL routing → View → Serializer → Model, ensuring server-side execution of all business rules.
- Commercial features are isolated in
apps/api/plane/license/to separate SaaS logic from the open-source core.
Frequently Asked Questions
Where is the main entry point for Plane's API backend?
The main entry point is the Django application configured in apps/api/plane. Within this module, apps/api/plane/api/urls/ defines the REST endpoint mappings, while apps/api/plane/web/views.py contains the ViewSets that serve as primary request handlers. The WSGI/ASGI configuration files at the project root delegate incoming requests to this application.
Does Plane's frontend contain any business logic?
No. The frontend packages located in packages/ui and packages/editor are React-based clients that consume the JSON API exposed by the Django backend. All validation, business rules, and data integrity checks reside server-side in apps/api/plane to ensure consistency across all clients, including the web UI, CLI tools, or third-party integrations.
How are database migrations handled in Plane's core logic?
Django migrations are managed alongside the models in apps/api/plane/db/models/. When you modify files like apps/api/plane/db/models/issue.py or apps/api/plane/db/models/project.py, you generate migrations using Django's makemigrations command. These migration files are stored in apps/api/plane/db/migrations/ and version-control schema changes alongside the model logic.
What is the purpose of the apps/api/plane/license/ directory?
This directory contains the SaaS-specific logic for Plane's commercial offerings. It manages instance registration, subscription status, and feature gating. While the core project management logic resides in other apps, this module ensures that enterprise features are properly licensed, as implemented in apps/api/plane/license/models/instance.py.
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 →