A Python framework for writing web applications properly.
$ uvx proper_new myapp
Type this command, and a new project will appear (requires uv)
Opinionated
by design
These are the ideas the framework will not compromise on - the rules that everything else is built around.
- 01
Humans read code. Machines just run it.
Writing code can - and should - be automated. But making that code easy to read and understand is the framework's reason for being.
- 02
Convention over configuration
You already know where things go. A Post model
lives at models/post.py. Its controller is
PostController in
controllers/post_controller.py. Its views are at
views/post/. This is not a suggestion - it is
a feature.
- 03
CRUD, always
Every controller maps URLs to the same seven actions - index, new, create, show, edit, update, delete. Remove those you don't need. Create another resource if you need more.
- 04
Sync above, async below
The runtime is ASGI. The code you write is not.
await is a hazard we've hidden behind a clean
interface - you get concurrency without the colour.
Batteries,
all of them
The boring parts of every web app - solved, documented, and ready to import. No assembly. No glue code. No "pick your favorite from the ecosystem."
Peewee ORM
A small, expressive ORM with migrations, query helpers, and async-safe connection handling.
peewee
Forms
Declarative forms with field validation, ORM integration, and rendering helpers.
proper.forms
Jx components
Server-rendered Python components - typed props, slots, and zero template language.
jx
Caching
Fragment, action, and low-level caching with SQLite or Redis backends.
proper.cache
Background tasks
Huey-powered queue with retries, schedules, and cron syntax.
huey
Templated transactional mail with SMTP and console mailers for development.
proper.emails
Authentication
Sessions, password resets, rate limiting, and pwned-password checks out of the box.
proper.auth
Internationalization
Locale-aware routing, translations, pluralization, and date formats.
proper.i18n
File storage
Disk and S3 adapters with signed URLs and image variants.
proper.storage
WebSockets
Channels, broadcasts, and presence on top of the same ASGI runtime.
proper.channel
$ proper g resource Post title:str body:text create tests/test_post.py skipped demo/router.py create demo/forms/post.py create demo/controllers/post_controller.py append demo/controllers/__init__.py create demo/views/post/ create demo/views/post/form.jx create demo/views/post/index.jx create demo/views/post/new.jx create demo/views/post/edit.jx create demo/views/post/show.jx append demo/models/__init__.py create demo/models/post.py
Scaffolds,
not snippets
Copy-paste is a tax on attention. Proper's generators produce complete, idiomatic, pre-tested files - so you read, not reassemble.
One command turns a resource into a model, controller, views, tests, and routes - wired together and ready to run.
- Almost suspicious, really.
For AI Agents
Build a Proper app, side by side with AI.
Drop the Proper skill into your skills folder and your AI agent will scaffold, edit, and refactor your app the Proper way: convention-aware, generator-first, idiomatic from the start.
Installed in your home folder, skills apply across every AI agent session.
# Step one: download the skill. $ mkdir -p ~/.claude/skills $ curl -LsSf https://properproject/skill.zip -o ~/.claude/skills/ # Step two: open your project. $ cd myapp # Step three: ask, plainly, for a thing. $ claude › add an OAuth login # Step four: read the code, obviously. # you are the one in charge