Show HN: Plain – The full-stack Python framework designed for humans and agents

Plain is a full-stack Python framework designed for both humans and AI agents, offering an explicit, typed, and predictable environment. It features built-in tooling for agents and is built on a modern stack including Python 3.13 and Postgres.
The full-stack Python framework designed for humans and agents.
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.
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 postgres
from plain.postgres import types
from plain.passwords.models import PasswordField
@postgres.register_model
class User(postgres.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: postgres.QuerySet[User] = postgres.QuerySet()
model_options = postgres.Options(
constraints=[
postgres.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),
]
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
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
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
30 first-party packages, one framework. All with built-in docs.
Foundation: plain, plain.postgres, plain.auth, plain.sessions Backend: plain.api, plain.jobs, plain.email, plain.cache, plain.redirection, plain.vendor Frontend: plain.htmx, plain.tailwind, plain.elements, plain.pages, plain.esbuild Development: plain.dev, plain.pytest, plain.toolbar, plain.code, plain.portal, plain.tunnel, plain.start Production: plain.admin, plain.observer, plain.flags, plain.scan, plain.pageviews, plain.support Users: plain.passwords, plain.oauth, plain.loginlink
Plain is a fork of Django, driven by ongoing development at PullApprove — with the freedom to reimagine it for the agentic era.
Source: Hacker News
















