Skip to content

Instantly share code, notes, and snippets.

@Vijesh2
Last active July 11, 2025 08:11
Show Gist options
  • Save Vijesh2/0965407f870f7dd60081480a7121df56 to your computer and use it in GitHub Desktop.
Save Vijesh2/0965407f870f7dd60081480a7121df56 to your computer and use it in GitHub Desktop.
When to use FastHTML() vs when to use fast_app()

fast_app() – when speed and sensible defaults matter

Typical scenario Why the wrapper helps
Proof-of-concepts, tutorials, Jupyter demos, small internal tools One call gives you an app plus a ready-to-use route decorator: app, rt = fast_app() (fastht.ml)
You like “batteries-included” defaults (PicoCSS, HTMX, Surreal scope JS, charset/meta tags, canonical link, session middleware, static-file routing) Those headers and routes are injected automatically; even PicoCSS is on by default (fastht.ml)
You want live-reload or a SQLite/Surreal “FastLite” DB with minimal ceremony The wrapper selects FastHTMLWithLiveReload when live=True, and can create tables + dataclasses when db_file/tbls are supplied (GitHub)

FastHTML() – when you need full control

Typical scenario Why you’d skip the wrapper
Larger code-bases, libraries, or mixed ASGI projects FastHTML is a thin subclass of Starlette; you can mount it, compose routers, or subclass it just as you would any ASGI app (fastht.ml)
Non-default headers, your own CSS/JS stack, custom session or CORS middleware, or no database at all You pass only the arguments you need; nothing is silently added.
Fine-grained lifecycle & testing Direct instantiation exposes every Starlette hook (routes, middleware, lifespan, etc.) and is what the test client examples use (fastht.ml)

Practical rule-of-thumb

  1. Start with fast_app() – it covers 80 % of cases and lets you ship a working app in a handful of lines.
  2. Switch to FastHTML() only when those smart defaults get in your way—e.g. you need a different CSS framework, must disable HTMX, manage sessions differently, or embed the app inside a larger ASGI ecosystem.

Technically, fast_app() just builds the same FastHTML object and then returns it, so there is no performance penalty—only extra convenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment