Awesome
fastapi-htmx-tailwind-example
Example application (IoT dashboard) built with FastAPI, HTMX, TailwindCSS, DaisyUI, Jinja, and MongoDB.
Goal
Create an extensive example project that integrates the following technologies:
FastAPI
as the backend application framework.HTMX
for frontend interactivity (no JavaScript, no npm required).- TailwindCSS and DaisyUI for styling.
Jinja2
for templating.- Async MongoDB with vanilla
Pydantic
for data persistence.
Among others, the project showcases the following topics:
FastAPI
andHTMX
integration usingFastHX
.- TailwindCSS and DaisyUI integration into a Python and
Jinja2
project withoutnpm
. - Async MongoDB usage with vanilla
Pydantic
andmotorhead
. - Single-command local development with
honcho
. - Using JSON instead of form data between the client and the server (
json-enc
HTMX extension), soPydantic
models can be used inFastAPI
routes. - Dynamic dialogs with
HTMX
and DaisyUI that are removed from the DOM when closed. - Lazy-loaded tables for faster initial page loading.
- Active search and filtering.
- Server-sent event streaming with
sse_starlette
, and client-side listening and dynamic UI updates withHTMX
and itssse
extension. - Custom server-side
HTMX
triggers using response headers withFastHX
for automatic UI updates.
Non-goals and caveats:
- Design, styling, and responsiveness (well, dashboard-like applications rarely work on small screens anyway).
- Testing: the backend code is very basic and uses standard tools, the main thing that should be tested is the frontend and its interactivity, but that's for a
selenium
tutorial project. - Full production readiness, see this section for more information.
Getting started
The following developer tools must be available:
- Python (^3.11)
- Docker
- Poetry
- Honcho
The project's dependencies can be installed with poetry install
.
The following poethepoet
tasks are defined in the project:
start
: Starts the FastAPI backend withuvicorn
.build-css
: Starts a process that watches.html
and.jinja
files and rebuilds the application's TailwindCSS file if necessary.build-prod-css
: Builds the minified, production TailwindCSS file of the application.check-format
: Executes theruff
format check.format
: Reformats the codebase withruff
.lint
: Executes theruff
linter.lint-fix
: Fixes linter errors withruff
.mypy
: Executes themypy
static code analysis with the project's own configuration.static-checks
: Executes all static checks (linting, formatting, type checking) in sequence.test
: Runs the test suite of the project.
These tasks can be executed with poetry run poe <task>
.
Running the project
Just execute honcho start
in the root directory. The command will spin up three processes:
database
: An empty MongoDB instance (usingdocker
) available on the default MongoDB port (27017
) in the host system. In case you have a MongoDB running on you host system, please change the port mapping and update the database connection string accordingly inapp/database.py
.css-builder
: Thebuild-css
task to make sure the tailwind CSS file of the project is always up to date during development.backend
: The FastAPI application.
The application will be available at http://127.0.0.1:10001/
(the port is configurable in .uvicorn.env
).
When started with honcho start
, the application will create some demo data. To prevent it from doing so, remove the CREATE_DEMO_DATA=true
part from the Procfile
's backend
process definition.
Notes
- Demo data creation happens in the application's lifespan to immediately have some data when the project is started. This is not a good practice though for development, because every server restart (code change) will trigger data creation. So if you're working on a project like, move data creation into a separate script or CLI (e.g. with
typer
). - Since the creation of this project,
fasthx
1.0
and then2.0
got released with new features that could simplify this project, for example by removing a few routes with duplicated internal logic. Check the fasthx releases for more details.
Development
Use ruff
for linting and formatting, mypy
for static code analysis, pytest
for testing, and poethepoet
as the task runner.
As mentioned above, use honcho start
to start the project, it automatically watches code changes and regenerates or restarts whatever is necessary for a convenient developer experience.
Contributing
All contributions and enhancements are welcome.
Note on TailwindCSS and DaisyUI
While TailwindCSS doesn't require npm
, getting plugins (e.g. DaisyUI) working does. In order to work around this limitation, this project loads the full, minified DaisyUI stylesheet from a CDN, which is quite bad for performance. Production applications should use npm
and configure TailwindCSS and the DaisyUI plugins as if it was a JavaScript project.
License - MIT
The project is open-sourced under the conditions of the MIT license.