
Feather - A Python framework built for AI assistants.
Flask on the backend, Tailwind CSS and HTMX on the front, and vanilla JavaScript only where the browser genuinely needs it. Authentication, an admin panel, background jobs and deployment are already written.
Every project ships the conventions an assistant should follow, and one command checks whether it followed them.
- Production features
- 14
- CLI commands
- 17
- Enforced conventions
- 13
- JavaScript frameworks
- 0
Tools you already know
Flask, Tailwind, HTMX, Vite and SQLAlchemy, wired together and configured. There are no experimental dependencies here, and nothing to set up before you start building.
SQLAlchemyBuilt for agentic development
The conventions live in the repository, a linter enforces them, and the assistant that wrote the code can run that linter itself.
Rules ship with it
A CLAUDE.md and an identical AGENTS.md are written into every new project, so whichever tool you use finds the conventions it needs. They are generated together and cannot drift apart.
Rules are enforced
feather check enforces thirteen of them and reports a file, a line and a fix for each problem. It exits non-zero, so it works as a pre-commit hook or a CI step.
Assistants self-verify
Four commands answer whether the work is sound: feather check, feather components, feather routes and feather test.
The loop
$ feather new myapp # scaffold the project
$ feather dev # run it
# describe the feature to your assistant
$ feather check # did it follow the conventions?
$ feather test # does it still work?Included out of the box
The work most apps repeat, done once and kept out of your way. All of it is optional. Turn a feature on when you create the project, or add it later.
Authentication
Google sign-in or a link by email, so there are no passwords to store. Approval workflows, roles and permissions come with it.
Admin panel
User approvals, role changes, growth charts and error logs, scaffolded into your app as code you can change.
Multi-tenancy
Tenants identified by email domain, with isolation enforced at the route, service and model layers.
Background jobs
A thread pool with concurrency limits, or RQ on Redis when losing a job would matter.
Caching
Cache a function result or a whole response, keyed by arguments, backed by memory or Redis.
File storage
One interface for local files and Google Cloud Storage, so moving between them is a config change.
Transactional email through Resend, with the result reported back to the user as a toast.
Dark mode
A toggle on every page including the admin, persisted in a cookie, with no flash of the wrong theme.
Security headers
CSP, HSTS and the rest applied in production without configuration. Override a directive when you need to.
Rate limiting
A decorator for development, and Flask-Limiter with Redis for limits that hold up across workers.
Events
Publish an event, subscribe somewhere else. Listeners run in the request or in the background.
Error logging
Exceptions land in the database with a stack trace, scoped to the tenant that hit them.
Health checks
Endpoints for load balancers, Kubernetes probes and the Docker healthcheck. You do not write them.
Request tracking
Every request gets an ID that shows up in the response headers and in every log line it produces.
How the frontend works
Start with components for anything static. Reach for HTMX when you need server data without a page reload. Use islands only when state has to live in the browser. Most features never get past the first two.
Components
Server-rendered Jinja2 macros. Buttons, cards, modals and inputs that render to HTML on the server, with no JavaScript and no hydration. Override any of them in your own app.
HTMX
Return a fragment of HTML from a route and swap it into the page. Forms, search, pagination and live updates, driven by attributes rather than a client-side framework.
Islands
For the UI that genuinely needs state in the browser, like drag-and-drop. Optimistic updates and rollback are built in, without React underneath.
Getting started
A scaffolded project has a fixed layout. Models, services and routes each have one home, and a file placed in one of them is registered without any wiring. An assistant writing a feature therefore has somewhere to put each file, and a rule set to write it against.

Scaffold it
Needs Python 3.11+ and Node.js 22+. The questions you answer here decide what gets generated: the database, whether there are user accounts, whether one organisation or many.
$ pip install feather-framework$ feather new myapp$ cd myapp && feather devLet the agent write it
Describe the feature. The assistant reads the conventions your project already carries, writes into the directories auto-discovery watches, and generates the migration for whatever models it added.
>Add a Post model with a title and a body, a service for creating and listing them, and page routes for the index and the detail view. Follow the conventions in CLAUDE.md, keep the logic in the service, and show me the migration before you apply it. Then run feather check and fix anything it reports.
Check it
Three commands tell you whether what came back is sound. Each exits non-zero on failure, so the same three work unchanged as a CI step.
$ feather check$ feather test$ feather security-checkDeploying is its own short path: feather docker init writes eight files that put the app behind Caddy on one server, with automatic HTTPS and a deploy that migrates once and waits for a health check. Read the deployment docs.

Fully open source
Feather is MIT licensed and built in the open. Work through the tutorial, open an issue when something breaks, and send a pull request if you want a say in where it goes next.