makeplane/plane
🔥🔥🔥 Open-source Jira, Linear, Monday, and ClickUp alternative. Plane is a modern project management platform to manage tasks, sprints, docs, and triage.
Healthy across the board
weakest axiscopyleft license (AGPL-3.0) — review compatibility
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓21+ active contributors
- ✓Distributed ownership (top contributor 45% of recent commits)
- ✓AGPL-3.0 licensed
- ✓CI configured
- ✓Tests present
- ⚠AGPL-3.0 is copyleft — check downstream compatibility
What would change the summary?
- →Use as dependency Failing → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the “Healthy” badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/makeplane/plane)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/makeplane/plane on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: makeplane/plane
Generated by RepoPilot · 2026-05-06 · Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/makeplane/plane shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO — Healthy across the board
- Last commit today
- 21+ active contributors
- Distributed ownership (top contributor 45% of recent commits)
- AGPL-3.0 licensed
- CI configured
- Tests present
- ⚠ AGPL-3.0 is copyleft — check downstream compatibility
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live makeplane/plane
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/makeplane/plane.
What it runs against: a local clone of makeplane/plane — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in makeplane/plane | Confirms the artifact applies here, not a fork |
| 2 | License is still AGPL-3.0 | Catches relicense before you depend on it |
| 3 | Default branch preview exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of makeplane/plane. If you don't
# have one yet, run these first:
#
# git clone https://github.com/makeplane/plane.git
# cd plane
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of makeplane/plane and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "makeplane/plane(\\.git)?\\b" \\
&& ok "origin remote is makeplane/plane" \\
|| miss "origin remote is not makeplane/plane (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(AGPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"AGPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is AGPL-3.0" \\
|| miss "license drift — was AGPL-3.0 at generation time"
# 3. Default branch
git rev-parse --verify preview >/dev/null 2>&1 \\
&& ok "default branch preview exists" \\
|| miss "default branch preview no longer exists"
# 4. Critical files exist
test -f "apps/admin/app/(all)/(dashboard)/layout.tsx" \\
&& ok "apps/admin/app/(all)/(dashboard)/layout.tsx" \\
|| miss "missing critical file: apps/admin/app/(all)/(dashboard)/layout.tsx"
test -f "apps/admin/app/(all)/(home)/page.tsx" \\
&& ok "apps/admin/app/(all)/(home)/page.tsx" \\
|| miss "missing critical file: apps/admin/app/(all)/(home)/page.tsx"
test -f ".env.example" \\
&& ok ".env.example" \\
|| miss "missing critical file: .env.example"
test -f "apps/admin/package.json" \\
&& ok "apps/admin/package.json" \\
|| miss "missing critical file: apps/admin/package.json"
test -f ".github/instructions/typescript.instructions.md" \\
&& ok ".github/instructions/typescript.instructions.md" \\
|| miss "missing critical file: .github/instructions/typescript.instructions.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/makeplane/plane"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
Plane is an open-source project management platform built with TypeScript/React (frontend) and Python (backend) that provides Jira/Linear/Monday.com-like functionality for managing tasks, sprints (called 'Cycles'), documents, and issue triage. It enables teams to track work items with rich-text editing, file uploads, sub-properties, and cross-issue references without the overhead of proprietary SaaS tools. Monorepo structure: apps/ contains frontend applications (admin, web, etc.) and backend services; each app has its own package.json and Dockerfile; shared code lives in workspace packages (@plane/hooks, @plane/ui, @plane/types, @plane/services, etc.). The admin app uses React Router for routing, MobX for state, and Tailwind CSS for styling.
Who it's for
Engineering teams and product managers who want self-hosted or cloud-based project management with full data control; contributors to the open-source community who understand TypeScript monorepos and React component patterns; instance admins who need to configure team settings via God mode.
Maturity & risk
Actively developed and production-ready: the repo shows a mature monorepo structure (12.6M LOC TypeScript, 3.6M Python), established CI/CD pipelines (GitHub Actions workflows for linting, testing, Docker builds), comprehensive issue templates, and CONTRIBUTING.md guidelines. The codebase uses Husky pre-commit hooks and strict linting (oxlint, oxfmt), indicating quality discipline, though the exact commit recency and test coverage are not visible from the file list.
Moderate risk factors: the monorepo spans multiple languages (TypeScript, Python, Docker, Nix) which increases onboarding friction and CI complexity; the admin app alone depends on 30+ packages including workspace-internal dependencies (@plane/*) that could introduce breaking changes; self-hosting variants (Docker, Kubernetes) add deployment complexity. No visible test file counts in the listing, making test coverage unclear.
Active areas of work
Active feature development visible from multiple app directories (admin app with authentication/AI configuration pages, main web app) and CI workflows for branch builds and PR validation. The repo includes deployment pipelines for feature branches and version checks, suggesting continuous delivery. Specific recent work is not visible from the file list, but the presence of .github/workflows/feature-deployment.yml indicates active feature flag or staging deployment work.
Get running
Clone the repo: git clone https://github.com/makeplane/plane.git && cd plane. Install dependencies with the workspace package manager (appears to use npm/pnpm based on .npmrc and monorepo structure): npm install or pnpm install. For the admin app specifically: cd apps/admin && npm run dev to start the development server on port 3001.
Daily commands:
cd apps/admin && npm run dev starts the React Router dev server on port 3001. For production build: npm run build && npm start. Type checking: npm run check:types. Linting: npm run check:lint. Format checking/fixing: npm run check:format and npm run fix:format.
Map of the codebase
apps/admin/app/(all)/(dashboard)/layout.tsx— Main dashboard layout component—establishes the foundational UI structure and navigation for all admin pages that every contributor must understand for page addition.apps/admin/app/(all)/(home)/page.tsx— Entry point for authentication and admin sign-in flow—core auth logic that gates access to the entire admin panel..env.example— Configuration template for all environment variables—mandatory reference for setting up local development and understanding required integrations.apps/admin/package.json— Admin app dependencies and build scripts—defines React Router setup, linting rules, and type generation that all contributors must follow..github/instructions/typescript.instructions.md— TypeScript/JavaScript coding standards and conventions—establishes patterns for type safety and code style that must be applied to all new code.CONTRIBUTING.md— Contribution guidelines for the entire Plane project—required reading for understanding PR workflow and code review expectations.apps/admin/app/(all)/(dashboard)/authentication/page.tsx— Authentication configuration hub—demonstrates admin panel's multi-provider pattern (GitHub, GitLab, Google, Gitea) that new integrations must follow.
Components & responsibilities
- Sign-In & Auth Flow — Authenticates admin user via email/password or OAuth providers (GitHub, GitLab, Google, Gitea); generates session JWT
How to make changes
Add a New Authentication Provider
- Create provider-specific directory following existing pattern (GitHub, GitLab, Google, Gitea) (
apps/admin/app/(all)/(dashboard)/authentication/[provider]/page.tsx) - Build configuration form component accepting provider API credentials (
apps/admin/app/(all)/(dashboard)/authentication/[provider]/form.tsx) - Add provider logo to assets directory (
apps/admin/app/assets/logos/[provider]-logo.svg) - Update authentication overview page to list new provider in menu (
apps/admin/app/(all)/(dashboard)/authentication/page.tsx) - Add environment variables to .env.example for provider credentials (
.env.example)
Add a New Admin Settings Page
- Create new directory under dashboard with (group) naming for URL organization (
apps/admin/app/(all)/(dashboard)/[feature-name]/page.tsx) - Build settings form component with validation and submission handlers (
apps/admin/app/(all)/(dashboard)/[feature-name]/form.tsx) - Add navigation link to sidebar-menu component to expose in navigation (
apps/admin/app/(all)/(dashboard)/sidebar-menu.tsx) - Include any modal components (e.g., test dialogs) alongside page (
apps/admin/app/(all)/(dashboard)/[feature-name]/[action]-modal.tsx)
Update Build & Lint Configuration
- Modify scripts section to add new linting or build tasks (
apps/admin/package.json) - Add oxlint rules for new code patterns if needed (
.oxlintrc.json) - Update TypeScript configuration in tsconfig if new module paths required (
apps/admin/tsconfig.json) - Run type generation and linting to verify (
apps/admin/package.json)
Why these technologies
- React Router v7 — Server-side rendering with file-based routing; chosen over Next.js for simpler server requirements and modern React Server Components support
- TypeScript — Type safety across authentication flows and form validation; prevents configuration errors in multi-provider OAuth setup
- oxlint / oxfmt — Rust-based linting and formatting for faster CI/CD and uniform code style across the monorepo (admin + other apps)
- App Router (group) layouts — Organizes authentication and dashboard as separate layout hierarchies; allows shared sidebar/navigation without coupling
Trade-offs already made
-
Single admin instance per Plane deployment
- Why: Simplifies configuration management and secrets handling
- Consequence: Admin UI cannot be horizontally scaled; single point of configuration failure requires careful deployment
-
Multi-provider OAuth (GitHub, GitLab, Google, Gitea) in UI
- Why: Enables flexible authentication for different organizational setups
- Consequence: Requires maintaining OAuth credential validation forms for each provider; onboarding complexity increases with each provider
-
Form-based configuration (email, image, instance settings)
- Why: User-friendly alternative to editing config files directly
- Consequence: Backend must validate and persist all settings; frontend cannot provide real-time validation without backend integration
-
React Router instead of Next.js for admin app
- Why: Lighter server footprint, fewer dependencies for self-hosted deployments
- Consequence: Loses Next.js ecosystem plugins; must implement custom server-side logic for authentication and API proxying
Non-goals (don't propose these)
- Real-time collaboration or live updates in admin UI (admin actions are synchronous)
- Multi-tenant admin isolation (single admin instance serves entire Plane deployment)
- Admin audit logging or change tracking (not in scope for v1.3.1)
- Admin role-based access control beyond single admin user
- API documentation generation from admin forms
Traps & gotchas
- The monorepo uses
workspace:*for internal dependencies (e.g.,@plane/types), which means changes in sibling packages require re-installation and a full rebuild—not just a file edit. 2) Husky pre-commit hooks enforceoxlint(759 max warnings currently allowed) andoxfmtformatting; commits will fail if these don't pass. 3) The admin app requires all @plane/* packages to be installed at the workspace root; missing these will cause module resolution errors. 4) Environment configuration uses.env.examplepattern; you must create a.env.localor.envfor local development, but the specific required vars are not listed in the file snippet. 5) React Router v7 is used (newer than you might expect), so routing patterns and loader/action conventions differ from older Next.js patterns.
Architecture
Concepts to learn
- Monorepo with Workspace Dependencies — Plane uses
workspace:*package references to manage interdependencies between @plane/hooks, @plane/types, @plane/ui, etc.; understanding this is essential to avoid 'module not found' errors and know when to rebuild. - React Router File-Based Routing — The admin app uses React Router v7's file-based routing (notice the directory structure
app/(all)/(dashboard)/) instead of explicit route configs; files are routes, so understanding this pattern is critical for adding pages. - MobX Observable State Management — Plane uses MobX for state management instead of Redux or Zustand; understanding
@observabledecorators,actionwrappers, and reactivity is necessary for modifying state logic. - Husky Git Hooks — Pre-commit hooks automatically run linting and formatting; PRs will fail CI if these don't pass locally first. Understanding how to bypass (with caution) or fix violations is essential.
- Burn-down Charts (Agile Metrics) — Plane's 'Cycles' feature uses burn-down charts to track sprint progress; understanding velocity, story points, and sprint metrics helps when implementing or modifying cycle tracking features.
- Multi-tenancy and God Mode — Plane supports instance-level admin configuration ('God mode') and per-workspace/team settings; understanding how to scope permissions and settings across tenants is important for admin features.
- Rich Text Editor with File Uploads — Work items support rich-text editing and file uploads for descriptions and attachments; knowing how Plane handles file storage, serialization, and rendering affects how you'd add new content features.
Related repos
jira-clone/jira— Open-source Jira clone with similar task/sprint management features; direct competitor in the same space.plane-dev/plane-web— Likely the main web app for Plane (sibling repo or branch); contains the primary user-facing interface.PostHog/posthog— Similar open-source product with strong self-hosting and analytics; comparable DevOps and deployment patterns.tldr-dev/tldr— Community-driven documentation tool; shows how open-source projects handle knowledge sharing at scale.mattermost/mattermost— Self-hosted team collaboration platform; shares Plane's self-hosting philosophy and monorepo complexity.
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add React Router v7 migration tests for admin app
The admin app uses React Router as its primary framework (not Next.js like other Plane apps), but there's no visible test suite for critical admin features like authentication forms (Gitea, GitHub, GitLab, Google), email configuration, and AI settings. Given the sensitive nature of admin routes and the migration to React Router, adding comprehensive tests would prevent regressions and ensure authentication flows work correctly across different providers.
- [ ] Create test file structure under apps/admin with tests directories mirroring apps/admin/app/(all)/(dashboard)/ structure
- [ ] Add unit tests for apps/admin/app/(all)/(dashboard)/authentication/*/form.tsx components using Vitest + React Testing Library
- [ ] Add integration tests for the email-config-form.tsx in apps/admin/app/(all)/(dashboard)/email/
- [ ] Add tests for form validation and API submission flows in apps/admin/app/(all)/(dashboard)/ai/form.tsx and apps/admin/app/(all)/(dashboard)/general/form.tsx
- [ ] Configure test runner in package.json with coverage thresholds and add to GitHub Actions workflow
Add pre-commit hook for admin app linting and type-checking
While .husky/pre-commit exists, there's no visible enforcement of the admin app's check:lint, check:types, and check:format scripts before commits. The admin app has strict linting (max-warnings=759) and TypeScript checks, but developers could bypass these. Adding a pre-commit hook specifically for the admin workspace would catch issues early and reduce CI failures.
- [ ] Review current .husky/pre-commit configuration and identify if it covers apps/admin
- [ ] Extend .husky/pre-commit to run 'oxlint --max-warnings=759' and 'tsc --noEmit' within apps/admin directory
- [ ] Add 'oxfmt --check' to pre-commit to enforce code formatting in admin app
- [ ] Test locally by making a linting/formatting violation in apps/admin and verifying it blocks the commit
- [ ] Document the updated pre-commit flow in CONTRIBUTING.md with examples specific to admin app development
Add E2E tests for admin authentication provider configuration workflows
The admin app has forms for configuring multiple OAuth providers (GitHub, GitLab, Google, Gitea) and email settings, but there's no visible E2E test coverage. This is critical infrastructure—misconfiguration could lock out users or expose secrets. Adding E2E tests (using Playwright or Cypress) would validate the full flow from form input to backend configuration.
- [ ] Create .github/workflows/e2e-admin-tests.yml GitHub Actions workflow file
- [ ] Set up Playwright (or Cypress) configuration for apps/admin with baseURL pointing to admin dev server
- [ ] Write E2E test suite covering: GitHub OAuth form validation and submission, GitLab OAuth configuration, Google OAuth secret handling, email SMTP configuration and test email sending
- [ ] Add environment variable examples to apps/admin/.env.example for E2E test credentials
- [ ] Integrate E2E workflow into PR pipeline alongside existing pull-request-build-lint-web-apps.yml
Good first issues
- Add TypeScript strict mode or stricter tsconfig rules to
apps/admin/tsconfig.jsonand fix any resulting type errors; improves type safety without new features. - Add missing test files for the authentication subdirectory (
apps/admin/app/(all)/(dashboard)/authentication/) which currently has no visible test suite, mirroring patterns from other app directories. - Improve documentation in
CONTRIBUTING.mdby adding a 'Workspace Package Map' section that explains what each@plane/*package exports and when to use each one; reduces onboarding friction.
Top contributors
- @sriramveeraghanta — 45 commits
- @dependabot[bot] — 9 commits
- @anmolsinghbhatia — 8 commits
- @b-saikrishnakanth — 6 commits
- @aaryan610 — 5 commits
Recent commits
4c1bdd1— fix(api): use requester's workspace role for project member role updates (GHSA-x63v-p7wc-47x4) (#9014) (sriramveeraghanta)ff21e53— fix(nginx): correct real_ip_header typo X-Forward-For → X-Forwarded-For (#8935) (MinitJain)9491bdb— fix(api): scope cross-workspace resource lookups to prevent IDOR (#9008) (sriramveeraghanta)a62fe8a— chore(deps): remove unused pnpm overrides (#8973) (sriramveeraghanta)db1c5b9— fix: filter out soft-deleted states from API endpoints (#8840) (KanteshMurade)a40e064— chore(deps): bump postcss (#8931) (dependabot[bot])32fb88a— chore(deps): bump axios, uuid and add security overrides (#8930) (sriramveeraghanta)03a2be8— chore(deps): bump lxml (#8925) (dependabot[bot])c62930e— chore: bump up the package version (sriramveeraghanta)f1d567a— chore: add Claude Code skills for PR descriptions and release notes (#8920) (sriramveeraghanta)
Security observations
- High · Hardcoded Default Credentials in .env.example —
.env.example. The .env.example file contains default credentials for critical services (PostgreSQL, Redis, RabbitMQ) with placeholder values like 'plane'. If developers copy this file directly to .env without changing credentials, the application will be deployed with known default credentials, allowing unauthorized access to databases and message queues. Fix: Add prominent comments indicating these must be changed before deployment. Consider implementing environment variable validation at startup that fails if defaults are detected in production. Use a secrets management system (e.g., HashiCorp Vault, AWS Secrets Manager) for credential storage. - High · Deprecated OpenAI API Key Pattern in Configuration —
.env.example. The .env.example contains OpenAI API configuration with example key format 'sk-'. While marked as deprecated, this could lead developers to hardcode actual API keys in this file or similar configuration files, which may be accidentally committed to version control. Fix: Remove deprecated configuration entries entirely. Implement secret scanning in CI/CD pipeline using tools like git-secrets or TruffleHog. Require all API keys to be provided through environment variables or secure secret management systems only. - Medium · AWS Credentials Exposure Risk —
.env.example. AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) are stored in environment configuration files. While .env files should not be committed, misconfiguration or accidents could expose these credentials. Fix: Use IAM roles instead of static credentials. If static credentials are necessary, implement automatic credential rotation. Use temporary security credentials (STS tokens). Implement AWS credential scanning in CI/CD pipelines and enable CloudTrail for monitoring access. - Medium · Minio/S3 Endpoint Configuration Exposure —
.env.example. The S3 endpoint URL and bucket name are exposed in configuration files. Combined with hardcoded credentials, this could allow direct unauthorized access to file storage. Fix: Implement proper IAM policies to restrict S3 access. Use bucket policies and public access blocks. Enable S3 encryption. Monitor S3 access logs. Consider using signed URLs for temporary file access instead of storing endpoint details in configuration. - Medium · Potential Insecure Deserialization with mobx and mobx-react —
package.json (dependencies: mobx, mobx-react). The dependency on mobx and mobx-react can be vectors for insecure deserialization if state is reconstructed from untrusted sources without proper validation. This is common in state management libraries. Fix: Validate and sanitize all deserialized state. Avoid deserializing code or functions from untrusted sources. Keep mobx and mobx-react updated to latest versions. Implement input validation for all state updates. - Medium · Missing Security Headers Configuration —
apps/admin/ root configuration. No evidence of security headers configuration (CSP, X-Frame-Options, X-Content-Type-Options, etc.) in the provided file structure. React Router apps need explicit security header configuration. Fix: Implement security headers via middleware or server configuration. Configure Content-Security-Policy (CSP) to prevent XSS attacks. Add X-Frame-Options, X-Content-Type-Options, and other protective headers. Consider using security middleware packages. - Medium · Exposed Admin Port Without Authentication Details —
apps/admin/.env.example, apps/admin/package.json. The admin application runs on port 3001 (from package.json scripts). There is no evidence of authentication/authorization middleware configuration in the visible structure, which could expose admin functionality. Fix: Implement strong authentication and authorization for admin routes. Use role-based access control (RBAC). Require multi-factor authentication (MFA) for admin access. Restrict admin interface to internal networks or VPNs if possible. - Medium · File Upload Size Limit Configuration —
.env.example (FILE_SIZE_LIMIT). FILE_SIZE_LIMIT is set to 5242880 bytes (5MB). While this has a limit, there's no evidence of additional validation such as file type checking, virus scanning, or storage quota per user. Fix: Implement file type whitelist validation on both client and server side. Add virus/malware scanning using tools like ClamAV. Implement
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.