# axum: HTTP routing for Rust that hands middleware to tower

> axum is an HTTP routing and request-handling library for Rust built on hyper and tower. Its defining choice is that it has no middleware system of its own, which is either the reason to adopt it or the reason to look elsewhere.

**tokio-rs/axum** — HTTP routing and request-handling library for Rust that focuses on ergonomics and modularity

- Repository: https://github.com/tokio-rs/axum
- Stars: 27,286 · Forks: 1,486
- Language: Rust
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/tokio-rs-axum

## The problem axum solves, and the team it fits

Rust web work usually splits into two jobs. One is moving bytes: accepting connections, parsing HTTP, writing responses. The other is deciding what a request means and what to send back. axum takes the second job and refuses to take the first, sitting on hyper for the transport side. The README describes it as an HTTP routing and request-handling library that focuses on ergonomics and modularity, and that wording is accurate rather than modest.

The audience follows from that split. If you are writing a JSON API, a webhook receiver, or an internal service inside a larger Rust system, axum gives you routes, request parsing and response generation without asking you to reorganise your application around it. If you are building a server-rendered site with templates, sessions, an admin interface and a migration tool, axum will feel like a bag of parts, because that is what it is. The README's own feature list never mentions templating, databases or background jobs. That is a boundary, not an oversight.

## No middleware system of its own: the tower::Service bet

The README is explicit that axum does not have its own middleware system and instead uses tower::Service. This is the design decision that separates it from frameworks that ship a bespoke layer or plugin API. A tower Service is a trait with a request type and a response type, and middleware is anything that wraps one service in another. Because axum's router is itself a service, layers compose around it the same way they compose around a hyper or tonic service.

The practical consequence is that timeouts, tracing, compression and authorization are not axum features. They are tower and tower-http features that axum inherits, and the README says exactly this: axum gets them for free. The cost is conceptual. You cannot learn axum's middleware model from axum's documentation alone, because there is no such model to learn. You learn tower's Service trait and the layer convention, and then axum routing is a thin surface on top.

Handlers are the other half of the mechanism. A handler is an async function whose arguments are extractors, and whose return value implements IntoResponse. In the README example, create_user takes Json(payload): Json<CreateUser> and returns (StatusCode, Json<User>). The extractor reads and deserialises the body, the tuple becomes a 201 response with a JSON body. Routing is declared with Router::new().route("/", get(root)).route("/users", post(create_user)), a macro-free API, which the README lists as a high level feature.

## Installing axum and running the README example

axum is published on crates.io, so it is added as a normal Cargo dependency rather than installed as a binary. The README does not give a cargo add line; the install path it documents is the crate itself plus the example project in the repository's examples directory. The workspace Cargo.toml sets rust-version = "1.80", and the README states the MSRV is 1.80, so an older toolchain will fail before anything else does.

The README's usage example is the first thing to run. It initialises tracing, builds a router with two routes, and serves it on port 3000:

```rust
let app = Router::new()
    .route("/", get(root))
    .route("/users", post(create_user));

let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await;
```

A GET to / should return the string "Hello, World!", and a POST to /users with a JSON body containing a username field should return 201 with a JSON user object. The README notes this example lives at examples/readme in the repository, alongside other example projects. If you want a working reference for a specific concern rather than a blank file, that examples directory is the place to look before writing your own scaffolding.

## Where axum is the wrong tool

The clearest limitation is the one the README states about the repository itself. The main branch is not what you should be reading. The README warns that the project is working towards axum 0.9, that main contains breaking changes, and that the 0.8.x branch is what is released to crates.io. Anyone who copies code from the GitHub default branch into a production service is copying unreleased API. The released versions are the axum-v0.8.9, axum-macros-v0.5.1 and axum-extra-v0.12.6 tags.

The second limitation is structural. If your team has no tower experience, axum's error messages and its middleware story will be harder than a framework with its own abstractions, because every layer you add is a tower type you must understand. The README's claim that axum is a relatively thin layer on top of hyper cuts both ways: little overhead, little insulation.

Third, axum is not a full-stack framework and does not pretend to be. There is no documented templating engine, no ORM, no session store, no admin generator. Projects that need those either assemble them from separate crates or pick something else. Choosing axum and then rebuilding a framework on top of it is more work than choosing the framework in the first place.

## axum against actix-web: two different centres of gravity

The most common comparison for a Rust HTTP library is actix-web, and the difference is architectural rather than a matter of taste. actix-web is built around its own actor-inspired runtime and its own middleware traits. Middleware in actix-web is written against actix-web's abstractions; you learn that framework's model to extend it.

axum inverts this. Its middleware is tower middleware, which means a layer written for axum is a tower layer, and the README notes that this lets you share middleware with applications written using hyper or tonic. If your organisation already runs gRPC services on tonic, that sharing is concrete: one timeout layer, one tracing layer, one authorization layer, applied in more than one server. With actix-web, that same layer would need a second implementation.

The trade is ecosystem depth. actix-web's own middleware catalogue and its longer history as a batteries-included web framework mean more problems already have a framework-specific answer. axum's answer is usually a tower-http crate or a layer you write. Neither is wrong; they optimise for different things. If you want the framework to own the whole stack, actix-web's centre of gravity is closer to that. If you want your HTTP layer to be a composable service inside a larger Rust system, axum's is.

## Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-09-18. The most recent releases are dated 2026-04-14: axum-v0.8.9, axum-macros-v0.5.1 and axum-extra-v0.12.6. The presence of release-plz.toml in the repository root suggests releases are automated, and the workspace is split into axum, axum-core, axum-extra and axum-macros, so version numbers move independently across those crates.

The upgrade cost is the part to plan for. The README's breaking-changes notice means the next minor line is not a drop-in. If you depend on axum = "0.8", a move to 0.9 will need a reading of the changelog and a compile pass, not just a version bump. The workspace also pins rust-version = "1.80", so an MSRV bump in a future release would force a toolchain upgrade across your build images.

Licensing is straightforward: the README states the project is licensed under the MIT license, and the repository root carries a LICENSE file. The contribution section states that unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in axum shall be licensed as MIT without additional terms. MIT is permissive and places few obligations on how you distribute a binary that links it, but the file that governs your use is the LICENSE in the repository, not this article, and anything beyond that is a question for your own legal review.

## Conclusion

Adopt axum if your service already lives in the tokio and tower world: you get routing, extractors and responses without a second middleware stack to learn, and any tower layer you write can be reused in hyper or tonic services. Do not adopt it if you want a framework that owns templating, an ORM, an admin panel and a project generator, because axum deliberately stops at HTTP. Before committing, check the branch you are reading: the README states that main currently contains breaking changes on the way to axum 0.9, and points at the 0.8.x branch for what is released to crates.io, so pin your dependency and read the changelog before upgrading.

## FAQ

### Does axum use Tokio?

The README's usage example runs on a #[tokio::main] async entry point and binds a tokio::net::TcpListener before calling axum::serve, so tokio is the runtime in the documented setup. axum itself is described as a thin layer on top of hyper.

### What is an axum server?

It is a Rust HTTP service built with axum's Router, which maps paths and methods to async handler functions. The README example binds a tokio TcpListener to 0.0.0.0:3000 and passes it to axum::serve together with the router.

### What is axum?

axum is an HTTP routing and request-handling library for Rust that focuses on ergonomics and modularity, according to its README. It uses tower::Service instead of defining its own middleware system.

## Sources

- [Issues](https://github.com/tokio-rs/axum/issues)
- [License: MIT](https://github.com/tokio-rs/axum/blob/main/LICENSE)
- [README](https://github.com/tokio-rs/axum/blob/main/README.md)
- [Releases](https://github.com/tokio-rs/axum/releases)
- [tokio-rs/axum on GitHub](https://github.com/tokio-rs/axum)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tokio-rs-axum
