Skip to content

dropseed/plain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35,413 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Plain

The full-stack Python framework designed for humans and agents.

Get started

mkdir my-app && cd my-app && claude "$(curl -sSf https://plainframework.com/start.md)"

Also works with Codex, Amp, OpenCode, or your agent of choice.

Why Plain?

Explicit, typed, and predictable. What's good for humans is good for agents.

Here's what Plain code looks like:

# app/users/models.py
from plain import models
from plain.models import types
from plain.passwords.models import PasswordField

@models.register_model
class User(models.Model):
    email: str = types.EmailField()
    password: str = PasswordField()
    display_name: str = types.CharField(max_length=100)
    is_admin: bool = types.BooleanField(default=False)
    created_at: datetime = types.DateTimeField(auto_now_add=True)

    query: models.QuerySet[User] = models.QuerySet()

    model_options = models.Options(
        constraints=[
            models.UniqueConstraint(fields=["email"], name="unique_email"),
        ],
    )

Views are class-based:

# app/users/views.py
from plain.views import DetailView
from .models import User

class UserDetail(DetailView):
    template_name = "users/detail.html"

    def get_object(self):
        return User.query.get(pk=self.url_kwargs["pk"])

URLs use a Router class:

# app/users/urls.py
from plain.urls import Router, path
from . import views

class UsersRouter(Router):
    namespace = "users"
    urls = [
        path("<int:pk>/", views.UserDetail),
    ]

Agent tooling

Plain projects include built-in tooling that agents use automatically.

Rules — Always-on guardrails stored in project rules files (e.g. .claude/rules/ for Claude Code). Short files (~50 lines) that prevent the most common mistakes.

Docs — Full framework documentation, accessible on demand from the command line:

plain docs models                      # full docs
plain docs models --section querying   # one section
plain docs models --api                # typed signatures only
plain docs --search "queryset"         # search across all packages

Skills — End-to-end workflows triggered by slash commands:

  • /plain-install — add a new package and walk through setup
  • /plain-upgrade — bump versions, read changelogs, apply breaking changes, run checks
  • /plain-optimize — capture performance traces, identify slow queries and N+1 problems, apply fixes
  • /plain-bug — collect context and submit a bug report as a GitHub issue

CLI

All commands run with uv run (e.g. uv run plain dev).

  • plain dev — start dev server with auto-reload and HTTPS
  • plain fix — format and lint Python, CSS, and JS in one command
  • plain check — linting, preflight, migration, and test validation
  • plain test — run tests (pytest)
  • plain docs --api — public API surface, formatted for LLMs

Stack

Plain is opinionated. These are the technologies it's built on:

  • Python: 3.13+
  • Database: Postgres
  • Templates: Jinja2
  • Frontend: htmx, Tailwind CSS
  • Python tooling: uv (packages), ruff (lint/format), ty (type checking) — all from Astral
  • JavaScript tooling: oxc (lint/format), esbuild (bundling)
  • Testing: pytest

Packages

29 first-party packages, one framework. All with built-in docs.

Foundation:

Backend:

Frontend:

Development:

Production:

Users:

About

Plain is a fork of Django, driven by ongoing development at PullApprove — with the freedom to reimagine it for the agentic era.

About

A web framework for building products with Python.

Topics

Resources

Contributing

Stars

Watchers

Forks

Contributors