Proper
Home
Proper Docs
Getting Started
Tutorial
Models
Peewee ORM
Relationships and Joins
Database Migrations
Controllers
Controllers Overview
Routing
Working with Forms
Static Assets
Controllers Advanced Topics
Views
Jx Components and Layouts
Rendering Forms
Other Components
Authentication
File Storage
Background Tasks
Internationalization (i18n)
Sending Emails
Channels
Going to Production
Caching
Security
Deployment and Performance
Digging Deeper
Testing Proper Applications
Models Advanced Topics
Building API-only Applications
Proper
A Python framework for writing web applications properly.
$ uvx proper_new myapp
Type this command, and a new project will appear<br>(requires uv)
Star on GitHub
Opinionated<br>by design
These are the ideas the framework will not compromise on - the<br>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<br>code easy to read and understand is the<br>framework's reason for being.
- 02
Convention over configuration
You already know where things go. A Post model<br>lives at models/post.py. Its controller is<br>PostController in<br>controllers/post_controller.py. Its views are at<br>views/pages/post/. This is not a suggestion - it is<br>a feature.
- 03
CRUD, always
Every controller maps URLs to the same seven actions - index, new,<br>create, show, edit, update, delete. Remove those you don't need.<br>Create another resource if you need more.
- 04
Sync above, async below
The runtime is ASGI. The code you write is not.<br>await is a hazard we've hidden behind a clean<br>interface - you get concurrency without the colour.
Batteries,<br>all of them
The boring parts of every web app - solved, documented, and ready<br>to import. No assembly. No glue code. No "pick your favorite from<br>the ecosystem."
Peewee ORM
A small, expressive ORM with migrations, query helpers, and<br>async-safe connection handling.
peewee
Forms
Declarative forms with field validation, ORM integration, and<br>rendering helpers.
proper.forms
Jx components
Server-rendered Python components - typed props, slots, and zero<br>template language.
jx
Caching
Fragment, action, and low-level caching with SQLite or Redis<br>backends.
proper.cache
Background tasks
Huey-powered queue with retries, schedules, and cron syntax.
huey
Templated transactional mail with SMTP and console mailers for<br>development.
proper.emails
Authentication
Sessions, password resets, rate limiting, and pwned-password<br>checks out of the box.
proper.auth
Internationalization
Locale-aware routing, translations, pluralization, and date<br>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<br>runtime.
proper.channel
WIP
WIP
$ proper g resource Post title:str body:text
create tests/pages/test_post.py<br>skipped demo/router.py<br>create demo/forms/post.py<br>create demo/controllers/post_controller.py<br>append demo/controllers/__init__.py<br>create demo/views/pages/post/<br>create demo/views/pages/post/form.jx<br>create demo/views/pages/post/index.jx<br>create demo/views/pages/post/new.jx<br>create demo/views/pages/post/edit.jx<br>create demo/views/pages/post/show.jx<br>append demo/models/__init__.py<br>create demo/models/post.py
Scaffolds,<br>not snippets
Copy-paste is a tax on attention. Proper's generators produce<br>complete, idiomatic, pre-tested files - so you read, not<br>reassemble.
One command turns a resource into a model, controller, views,<br>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<br>agent will scaffold, edit, and refactor your app the Proper way:<br>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.<br>$ mkdir -p ~/.claude/skills<br>$ curl -LsSf https://properproject/skill.zip -o ~/.claude/skills/
# Step two: open your project.<br>$ cd myapp
# Step three: ask, plainly, for a thing.<br>$ claude<br>› add an OAuth login
# Step four: read the code, obviously .<br># you are the one in charge