Framework
dj-bolt/django-bolt avatar
dj-bolt/django-bolt

django-bolt puts Actix Web under Django and calls it a production server

The fastest Python web framework, built on Django. Rust (Actix Web) HTTP server + async typed handlers + msgspec, with the full Django ORM, Admin, middleware and auth. 300k+ req/s, no gunicorn/uvicorn.

1,755 stars93 forksPythonLicense varies

At a glance

What is it?
django-bolt serves Django endpoints from an Actix Web and Tokio runtime in Rust, bridging to Python handlers through PyO3 and serializing with msgspec. The pitch is a DRF replacement you can adopt one endpoint at a time, and the cost is a compiled extension, an alpha status and a very recent release cadence.
Who is it for?
Adopt django-bolt if you have an existing Django project with DRF endpoints and want typed async handlers without giving up the ORM, Admin or middleware, and you are willing to build a compiled wheel. Do not adopt it for a green field service or for anything that cannot tolerate an alpha framework classified as Development Status :: 3 - Alpha.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Routing runs in Rust, handlers still run in Python

The architecture is a three part split, and each part comes from a different project.

HTTP parsing, routing, auth, guards, CORS, rate limiting and compression run in Rust without taking the GIL. The Rust side is Actix Web on Tokio, bridged to Python through PyO3, with serialization handled by msgspec. Your handlers stay plain Python and keep using the Django ORM.

`Cargo.toml` names the pieces and their versions: `actix-web = 4` with gzip, brotli and zstd compression plus cookies, `actix-http = 3`, `actix-web-actors = 4` and `actix = 0.13` for WebSocket support, `actix-files = 0.6` for static file serving, and `tokio = 1` with the `full` feature. Middleware dependencies are equally explicit: `governor = 0.10` for rate limiting, `jsonwebtoken = 10` with the `aws_lc_rs` feature for JWT authentication, `dashmap` for concurrent rate limit state and `parking_lot` for shared locks. Router matching uses `matchit = 0.9`.

Two details in that file are worth reading twice. First, `pyo3 = 0.29.2` with the `abi3-py312` feature, which gives one stable ABI wheel for every GIL build from 3.12 upward; the comment explains that the free-threaded build has no stable ABI before 3.15, so PyO3 ignores the abi3 feature there and builds a version specific `cp314t` module. Second, `memchr = 2` is listed as SIMD byte search for the path param decode check, and `mimalloc` and `tikv-jemallocator` are optional allocator features.

The build backend is maturin, declared as `requires = ["maturin>=1.8,<2.0"]`, with a `rust-toolchain.toml` and a `build.rs` at the root and the Rust code in `crates/` and `src/`.

The consequence for a user is blunt: this is a compiled package. If no wheel matches your platform, you need a Rust toolchain to build it.

runbolt replaces gunicorn and uvicorn

The framework ships its own server command, and that is the central claim: `runbolt` is the production server, so no gunicorn or uvicorn is required.

The README frames the target as people who think of Django REST Framework or Django Ninja but want a Rust engine underneath. Two run modes are shown:

bash
python manage.py runbolt --dev              # auto-reload for development
python manage.py runbolt --processes 4      # production: multi-process, no gunicorn/uvicorn

The production mode is described in the feature table as multi-process with `SO_REUSEPORT`, worker recycling, graceful shutdown, and static and media serving. `SO_REUSEPORT` is what lets several processes bind the same listening socket, which is the usual way to scale an HTTP server across cores without a proxy in front.

Installation is one command, and adding it to a project is one entry in `INSTALLED_APPS`:

bash
pip install django-bolt      # or: uv add django-bolt
python
# myproject/settings.py
INSTALLED_APPS = [
    ...,
    "django_bolt",
]

Endpoints live in an `api.py` placed next to `settings.py` or inside any Django app, and the README notes Bolt autodiscovers them. A minimal endpoint is a decorator on an async function, and a declared return type is validated on the way out:

python
from django_bolt import BoltAPI

api = BoltAPI()

class UserSchema(msgspec.Struct):
    id: int
    username: str

@api.get("/users/{user_id}")
async def get_user(user_id: int) -> UserSchema:
    user = await User.objects.aget(id=user_id)
    return {"id": user.id, "username": user.username}

The ORM call is `aget`, Django's async single row getter, with no extra configuration. The API then answers at `http://localhost:8000/users/1` with interactive docs at `http://localhost:8000/docs`.

Type hints do validation in both directions

Request validation is driven entirely by annotations, which is the part that makes this feel different from DRF.

A struct declared as a `msgspec.Struct` parameter becomes a validated JSON body. A parameter annotated with `Annotated[str, Header("x-api-key")]` becomes a required header. A plain parameter with a default becomes a query parameter:

python
@api.post("/users", status_code=201)
async def create_user(
    user: CreateUser,
    api_key: Annotated[str, Header("x-api-key")],
    page: int = 1,
):
    return {"username": user.username, "page": page}

Auth and guards are declared on the route rather than in middleware. The README states that JWT signature checks, expiry, API-key lookup and guard evaluation happen before the GIL is ever taken:

python
from django_bolt.auth import JWTAuthentication, IsAuthenticated, Requires

IsStaff = Requires("is_staff", True)

@api.get("/admin/stats", auth=[JWTAuthentication()], guards=[IsAuthenticated(), IsStaff])
async def admin_stats(request):
    return {"user_id": request.user.id}

For model backed endpoints there is a `ModelViewSet` and a `Serializer` with field sets per action, which is a closer match to DRF's ModelSerializer:

python
from django_bolt import ModelViewSet, PageNumberPagination
from django_bolt.serializers import Serializer
from myapp.models import Article

class ArticleSchema(Serializer):
    id: int
    title: str
    content: str

    class Config:
        field_sets = {"list": ["id", "title"]}

The batteries list in the README also covers OpenAPI docs through Swagger, ReDoc, Scalar, RapiDoc and Stoplight, JWT and API key auth, guards, pagination, WebSockets, SSE, streaming, a testing client and MCP server support.

Alpha status, a 0.x version and a busy release train

The numbers around this project are moving fast, and the metadata is where the caution lives.

`pyproject.toml` sets `version = "0.12.0"`, `requires-python = ">=3.12"`, and classifies the package as `Development Status:: 3 - Alpha`. It declares support for Django 5.2, 6.0 and 6.1, Python 3.12 through 3.14, and carries the classifier `Programming Language:: Python:: Free Threading:: 2 - Beta`. Runtime dependencies are `Django>=5.2`, `asgiref>=3.12`, `click>=8.1`, `httpx>=0.28.1`, `msgspec>=0.20`, `pyjwt>=2.10.1` and `typing-extensions`.

The release train is short and recent: v0.12.0-rc3 on 2026-09-21, v0.12.0-rc4 on 2026-10-03, and v0.12.0 on 2026-10-11. The last push was on 2026-10-14, three days after the stable tag, so the branch is ahead of the release you would install.

The licence needs a direct note. The README badge links to the MIT licence page and `pyproject.toml` records `license = { text = "MIT" }` with the OSI approved classifier, while the repository's own licence field is unclassified. The `Cargo.toml` workspace also declares `license = "MIT"` and its repository as `https://github.com/dj-bolt/django-bolt`, while the README homepage is `bolt.farhana.li/`. Two of those three agree, and the LICENSE file in the repository is the one to read if this matters to you. That is a fact about the files, not legal advice.

Development uses `just`, with a `justfile` at the root rather than a Makefile. The default recipes include `build` running `uv run maturin develop`, `build-release` adding `--release`, and a separate free-threaded path where `build-ft` syncs Python 3.14t into its own `.venv-ft` environment so the default virtualenv stays untouched. Running the free-threaded tests has a guard that exits with a message telling you to run `just build-ft` first, because `uv run` can otherwise create the environment with a GIL build.

The benchmark claim, stated with its conditions

The performance claim deserves to be read as carefully as the README writes it, because the README states the conditions.

The claim is 300k+ requests per second on a single 12-core desktop, with 8 processes, C=100 and loopback, ahead of FastAPI and Robyn and also of Bun based JavaScript frameworks such as Elysia and Hono on JSON payloads. Those are the qualifiers: one machine, eight processes, a fixed concurrency of 100, and loopback traffic. It is a JSON throughput number on loopback, not a latency or a database bound result.

The `justfile` explains the benchmark parameters and, more usefully, why they are what they are. The defaults are host `127.0.0.1`, port `8001`, `c := "100"`, `p := "8"`, and `n := "100000"` requests, with the comment that 100k requests take roughly 0.3 to 1s per endpoint at typical RPS. It also records that a smaller 10k run finished in about 40ms on fast endpoints, which was mostly connection ramp transient and produced plus or minus 25 percent run to run noise that made comparisons meaningless. So the harness author picked the request count to get past the noise floor, which is a good sign about the rig.

The same file also carries the benchmark port for a throwaway PostgreSQL server at `55432` used by `just test-pg`, which tells you the framework's own test and benchmark work covers a database backed path as well.

The benchmark page is at `bolt.farhana.li/benchmarks/` and a video tutorial is linked from the README header. Neither has been consulted for this article.

Editorial conclusion

Adopt django-bolt if you have an existing Django project with DRF endpoints and want typed async handlers without giving up the ORM, Admin or middleware, and you are willing to build a compiled wheel. Do not adopt it for a green field service or for anything that cannot tolerate an alpha framework classified as Development Status :: 3 - Alpha. Verify first that a wheel exists for your interpreter and platform, that `python manage.py runbolt --processes 4` starts on your target host, and read the licence file, since the metadata records MIT while the repository field shows an unclassified licence.

Frequently asked questions

How do I install and run django-bolt?

Run pip install django-bolt (or uv add django-bolt), add "django_bolt" to INSTALLED_APPS, define endpoints in an api.py, and start the server with python manage.py runbolt --dev or python manage.py runbolt --processes 4 for production.

Do I still need gunicorn or uvicorn with django-bolt?

No. The README states runbolt is the production server, providing multi-process with SO_REUSEPORT, worker recycling, graceful shutdown, and static and media serving. The HTTP server itself is Actix Web with Tokio.

How does django-bolt handle request validation?

Type hints drive it. A msgspec.Struct parameter is validated as a JSON body, an Annotated parameter with Header marks a header, a parameter with a default becomes a query parameter, and a declared return type is validated on the way out.

What are the version requirements for django-bolt?

pyproject.toml sets requires-python to >=3.12 and depends on Django>=5.2, with classifiers for Django 5.2, 6.0 and 6.1 and Python 3.12 through 3.14. The PyO3 abi3-py312 feature gives one wheel for GIL builds from 3.12, while free-threaded builds are version specific.

Is django-bolt production ready?

The project classifies itself as Development Status :: 3 - Alpha at version 0.12.0, which shipped on 2026-10-11 after three release candidates in the same month. The repository is not archived and the last push was on 2026-10-14.

Official sources

  1. dj-bolt/django-bolt on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dj-bolt-django-bolt.svg)](https://hysenlabs.com/projects/dj-bolt-django-bolt)

Was this useful?