Interactive WTForms forms declared in Python and powered by htmx, with no JavaScript to write, or even any htmx.

Here's (almost) everything wtforms-htmx adds on top of a regular form:
class PostForm(HtmxForm):
title = StringField().triggers("slug", slugify)
slug = StringField()- Declare interactivity in Python.
Right on the field declaration, not scattered across
hx-*attributes. - No extra endpoints. Interactions are handled by the form's existing view. You don't write a route for each one.
- Progressive enhancement. The form works without JavaScript; htmx layers live updates and partial swaps on top. Same form, two render paths.
- Opinionated defaults, fully overridable. wtforms-htmx renders
the right
hx-*for you, but they're yours to override. - Common patterns in a few lines. Inline validation and
FieldListadd/remove/reorder are built in. The examples show how to build autocomplete, comboboxes and dependent fields.
Full documentation: https://wtforms-htmx.readthedocs.io/
- wtforms-htmx-components provides ready-made interactive fields, such as a combobox.
- flask-wtforms-htmx
provides
HtmxFlaskForm, a drop-inFlaskFormfor Flask-WTF.
A runnable gallery of examples lives in examples/. The
documentation shows most of them with a
screencast. To run it locally:
uv sync --group example
uv run python -m examplesThen open http://127.0.0.1:5000/.