Web development framework that brings the Next.js developer experience to Python, built on FastAPI, htmy, and FastHX.
Project description
Source code: https://github.com/volfpeter/holm
Documentation and examples: https://volfpeter.github.io/holm
holm
Web development framework that brings the Next.js developer experience to Python, built on FastAPI, htmy, and FastHX.
Key features
- Next.js-like developer experience with file-system based routing and page composition.
- Standard FastAPI everywhere, so you can leverage the entire FastAPI ecosystem.
- JSX-like syntax with async support for components, thanks to
htmy. - First class HTMX support with
FastHX. - Async support everywhere, from APIs and dependencies all the way to UI components.
- Support for both JSON and HTML (server side rendering) APIs.
- No JavaScript dependencies
- No build steps, just server side rendering with fully typed Python.
- Stability by building only on the core feature set of dependent libraries.
- Unopinionated: use any CSS framework for styling and any JavaScript framework for UI interactivity.
Pre-requisite knowledge
To get started, all you need is a basic understanding of:
- FastAPI: the underlying web framework.
- htmy: the used component / templating and rendering library.
- HTML and CSS fundamentals.
Familiarity with FastHX (the rendering layer between htmy and FastAPI), and especially its htmy integration is useful, but not necessary, unless you are building an HTMX application.
It is recommended to use HTMX, if for nothing else, then to avoid hard page loads on navigation. hx-boost (or navigation with hx-get) offers the same benefits as the Link component in Next.js.
Installation
The package is available on PyPI and can be installed with:
pip install holm
Supported operating systems:
- Linux
- macOS
- Windows: WSL only (native support may arrive in the future)
Support
Consider supporting the development and maintenance of the project through sponsoring, or reach out for consulting so you can get the most out of the library.
Application structure
Similarly to Next.js, holm is built around the concept of file-system based routing. This essentially means that your code structure is automatically mapped to a matching API:
- You do not need to manually define routes, every application component is automatically discovered and registered in the application.
- You do not need to manually wrap pages in their layouts, it is automatically done based on your application's code structure.
You can find all the necessary details on the Application component page, and the Quick start guide can walk you through the process of creating your first application. The two are complementary documents, reading both is strongly recommended.
HTML rendering is also fully automated, in the vast majority of cases you do not need to concern yourself with that (the only exceptions are HTML APIs, more on that below).
All you need to do is follow these simple rules:
- You must initialize your application instance using
holm.App(). It optionally accepts a baseFastAPIapplication and afasthx.htmy.HTMYinstance that handles HTML rendering. holm.App()must be called directly within a module in your root application package to make automatic application discovery work.
Examples
If you prefer to learn through examples, the Quick start guide is the best place to start.
To learn about creating rendering APIs and adding HTMX to your application, you should have a look at the Rendering APIs with HTMX guide.
You can discover even more features by exploring the test application of the project.
If you are looking for the simplest possible application you can create, then can find it in the examples/minimal directory of the repository.
Security
At the moment, the library does not provide security features like automatic CSRF prevention out of the box. A custom form component and a corresponding middleware may be added to the library later, but of course 3rd party implementations are very welcome! Alternative solutions include JavaScript, but the library aims to remain unopinionated, especially on the client front. If you use HTMX, you should check out their CSRF prevention recommendation, just keep in mind that the <body> tag is not swapped for boosted requests.
Also, do not forget about XSS prevention, when rendering untrusted data with custom components!
AI assistance
The library and all its dependencies are registered at Context7.
To get good AI assistance, all you need to do is register the Context7 MCP server in your coding tool and tell the agent to use it.
If you are starting a new project, you can additionally point the agent at one of the example applications in the repository. With all this context and detailed instructions of the project you want to build, it will get you started quickly.
Because of the similarity with Next.js and React, and the standard use of FastAPI and other dependencies, you can expect good results, both for vibe coding or inline completion.
Development
Development setup:
uvfor project and dependency management.poethepoetfor running tasks. Runuv run poeto see all available tasks.mypyfor static code analysis.ruffis used for formatting and linting.pytestfor testing.mkdocs-materialandmkdocstringsfor documentation.
Tests are located in the tests directory and they use the application defined in the test_app package (through a TestClient). This setup makes it possible to run test_app outside of tests, which is useful for debugging.
You can run all tests with uv run poe test. You can separately start the test application with uv run poe test-app.
Contributing
We welcome contributions from the community to help improve the project! Whether you're an experienced developer or just starting out, there are many ways you can contribute:
- Discuss: Join our Discussion Board to ask questions, share ideas, provide feedback, and engage with the community.
- Document: Help improve the documentation by fixing typos, adding examples, and updating guides to make it easier for others to use the project.
- Develop: Prototype requested features or pick up issues from the issue tracker.
- Test: Write tests to improve coverage and reliability.
Comparison with other frameworks
Frameworks with JavaScript dependencies
The most prominent frameworks in this category are Reflex and NiceGUI. They both provide a Python-first web development experience while using complex JavaScript frameworks under the hood for constructing user interfaces (namely React and Vue.js). They take care of state management and synchronization (using WebSockets), seamlessly connecting the JavaScript frontend and the Python backend. In exchange for this convenience comes complexity and heavy reliance on the ever-changing JavaScript ecosystem.
holm comes with no JavaScript dependencies, but that doesn't mean you can't use JavaScript to add frontend interactivity. In fact, it comes with first class HTMX support and naturally works with frameworks like Alpine.js. Web component frameworks like lit, and even React application segments can also be integrated, just like into any server rendered page.
Pure server-side rendering frameworks
This category includes frameworks like FastHTML or Ludic, and this is where holm belongs as well, but it has some key differentiators.
First, holm brings the Next.js developer experience to Python with file-system based routing, automatic layout composition, and dynamic page metadata creation, and more. Thanks to htmy, it supports async code throughout the stack, even in components, and it also solves the prop drilling problem. While being built with htmy, it is easy to integrate with other templating libraries, like Jinja or htpy. And it provides all these features using standard, simple FastAPI patterns.
License
The package is open-sourced under the conditions of the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file holm-0.3.0.tar.gz.
File metadata
- Download URL: holm-0.3.0.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb8c5bae4904100aa9624115f19163813f4b162082f72b81a6ae0e7a82ee9287
|
|
| MD5 |
3ecca77e47c617d38a3e94dab1c09964
|
|
| BLAKE2b-256 |
b2e020c6611c9a150b28bbf03e87035fee4a8f7e98c8db677a4df0ad02a1d914
|
Provenance
The following attestation bundles were made for holm-0.3.0.tar.gz:
Publisher:
publish.yml on volfpeter/holm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
holm-0.3.0.tar.gz -
Subject digest:
eb8c5bae4904100aa9624115f19163813f4b162082f72b81a6ae0e7a82ee9287 - Sigstore transparency entry: 563554923
- Sigstore integration time:
-
Permalink:
volfpeter/holm@c23bb080c545a29956d63e677d7b6d77e4259afb -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/volfpeter
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c23bb080c545a29956d63e677d7b6d77e4259afb -
Trigger Event:
release
-
Statement type:
File details
Details for the file holm-0.3.0-py3-none-any.whl.
File metadata
- Download URL: holm-0.3.0-py3-none-any.whl
- Upload date:
- Size: 17.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e4bfd5cd3bd91e9833fa121c2ed48e34329a906cd53236a88dc111e24d6f5e8
|
|
| MD5 |
80bdb9bb441f5d24c3e19ccfaa78e2f1
|
|
| BLAKE2b-256 |
478e5ad18e26f8c03b807f8cab272e518ab6d1077a12f4e52f7f8a3d7d2e0217
|
Provenance
The following attestation bundles were made for holm-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on volfpeter/holm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
holm-0.3.0-py3-none-any.whl -
Subject digest:
7e4bfd5cd3bd91e9833fa121c2ed48e34329a906cd53236a88dc111e24d6f5e8 - Sigstore transparency entry: 563554934
- Sigstore integration time:
-
Permalink:
volfpeter/holm@c23bb080c545a29956d63e677d7b6d77e4259afb -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/volfpeter
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c23bb080c545a29956d63e677d7b6d77e4259afb -
Trigger Event:
release
-
Statement type: