Chirp does not enforce a project layout. This page shows where files go in an app
generated bychirp new— handlers, templates, static assets, and tests.
Routing follows the filesystem underpages/, so directory structure is part of
your app's behavior, not just housekeeping. New to that idea? See
how pages map to URLs.
Recommended Structure
The defaultchirp new myappscaffold generates an auth-and-dashboard starter:
myapp/
app.py # App instance, middleware, auth routes, entry point
models.py # User model + password verification helpers
pyproject.toml # Project metadata and dependencies
AGENTS.md # Guidance for coding agents working in this app
pages/
_layout.html # Shared page layout (defines {% block content %})
page.py # Home route handler
page.html # Home template
login/
page.py # Login page handler
page.html # Login template
dashboard/
page.py # Protected dashboard handler
page.html # Dashboard template
static/
style.css # CSS, JS, images
theme.css # Optional ChirpUI token overrides
migrations/ # SQL migration files (empty to start)
README.md
tests/
conftest.py # Test import setup
test_app.py # Auth flow + smoke tests
Thepages/ tree also recognizes other special files — _context.py,
_meta.py, and _actions.py— that the default scaffold does not write but the
filesystem router reads when present. See
filesystem routing for the
full set.
Key Directories
| Directory | Purpose |
|---|---|
app.py |
App creation, middleware setup, auth routes,if __name__ == "__main__": app.run() |
models.py |
User model and credential verification helpers for scaffolded auth |
pages/ |
Filesystem routes. Paths are relative toAppConfig(template_dir="pages"). |
static/ |
CSS, JS, images. Served at/staticby default. |
migrations/ |
SQL migration files.chirp makemigrationswrites here. |
tests/ |
Pytest tests. UseTestClient(app)for requests. |
Scaffold Variants
chirp newaccepts flags that change the starting layout. Every variant still
writespyproject.toml, AGENTS.md, and an empty migrations/directory.
The auth + dashboard starter above (chirp new myapp). Filesystem routing under
pages/, a login flow, and a protected dashboard. This is the recommended
starting point for a real app.
chirp new myapp --minimal— a single-file app with one template:
myapp/
app.py
templates/
index.html
Drops thepages/tree, models, and scaffolded auth routes. Good for a quick
prototype or a one-route service.
chirp new myapp --sse— adds a Server-Sent Events starter:
myapp/
app.py # Adds an EventStream route at /stream
templates/
index.html # Extends the boost layout, calls sse_scope(...)
static/
style.css
tests/
test_app.py
The template extendschirp/layouts/boost.htmland wires the SSE connection with
thesse_scopemacro.
chirp new myapp --shell— a persistent app shell (topbar, sidebar) with a nested
items/ section and a cascading _context.py. Use this for dashboard-style apps
where the chrome stays put across navigations.
Customizing
These are fields on AppConfig, a frozen dataclass:
- Template directory:
AppConfig(template_dir="pages") - Static directory:
AppConfig(static_dir="assets") - Component libraries:
AppConfig(component_dirs=("components",))for shared partials
Next Steps
- Installation — Install Chirp
- Quickstart — Build your first app
- First Fragment App — Build the smallest complete htmx-backed app
- Filesystem routing — how directory structure maps to URLs
- Configuration — the full AppConfig field catalog
- Auth hardening — the secure-by-default middleware stack