# tokio-rs/axum — codebase unpack

> Canonical page: https://codevetter.com/unpack/axum

This is a deterministic Repo Unpack scan of tokio-rs/axum — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: f8b02f22cf10bee707bda19b58265b9e33677535 (2026-09-30)
- Last upstream commit: axum: Don't wrap merged service routes in another Route (#3909)
- Generated by codevetter 1.15.0 on 2026-10-02
- 500 files scanned · 1.7 MB

Source inspection; upstream code and tests were not executed.

## Languages

- Rust: 301 files
- TOML: 64 files
- Markdown: 39 files
- HTML: 8 files
- JavaScript: 5 files
- YAML: 5 files
- SQL: 4 files
- JSON: 2 files

## Repository structure

- axum-macros/ — 184 files
- examples/ — 153 files
- axum/ — 85 files
- axum-extra/ — 37 files
- axum-core/ — 23 files
- .github/ — 8 files
- contrib/ — 1 files

Probable source entrypoint: `Cargo.toml` (inferred from the tree, not upstream docs)

## Source layout — axum/

- axum/benches/ — 1 file
- axum/src/ — 79 files
- axum/tests/ — 1 file
- axum/CHANGELOG.md — 1 file
- axum/Cargo.toml — 1 file
- axum/LICENSE — 1 file
- axum/README.md — 1 file

## Package

- Cargo.toml: null — 0 declared dependencies

## Structural health signals

Average score 6.7/10 across 96 files; 27 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- f8b02f22cf10 (2026-09-30) axum: Don't wrap merged service routes in another Route (#3909)
- 83366c2b2755 (2026-09-29) chore(deps): bump crate-ci/typos from 1.50.2 to 1.50.3 (#3908)
- d775cb202bea (2026-09-28) examples: Remove unused axum-extra dependency (#3906)
- 09e767e6667b (2026-09-28) axum-extra: Avoid duplicate typed header error output (#3903)
- bc8d49124352 (2026-09-25) feat: add InnerPath extractor (#3856)

## Overview

Axum is a Rust HTTP routing and request-handling library for developers building asynchronous services with Tokio, Hyper, and Tower. Its distinctive interface connects ordinary async handlers to typed request extractors and response conversions, while reusing Tower middleware rather than introducing a separate middleware protocol. This brief examines commit f8b02f22cf10bee707bda19b58265b9e33677535, including the four library crates, every listed binary entrypoint, selected internals, tests, and CI; the inspection is bounded, and no repository code or tests were executed.

## System map

The repository is a library ecosystem with application examples, rather than one deployable service. The root workspace divides foundational contracts, HTTP execution, optional utilities, and procedural macros across four crates. Example binaries assemble their own listeners, application state, middleware, and external integrations in a separate workspace. Build and release behavior is described by Cargo manifests and GitHub Actions.
- The root workspace includes axum and axum-* members, uses resolver 2, declares Rust 1.80, and forbids unsafe code through workspace lints. — [Cargo.toml#L1-L14](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/Cargo.toml#L1-L14)
- axum-core exposes body, extract, response, RequestExt, and RequestPartsExt; its crate documentation recommends it for libraries implementing FromRequest or IntoResponse. — [axum-core/src/lib.rs#L1-L33](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/lib.rs#L1-L33)
- axum explicitly targets Tokio and Hyper; runtime and transport independence are not stated goals, while Tower Service supplies its middleware integration. — [axum/src/lib.rs#L12-L21](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/lib.rs#L12-L21)
- Router stores an Arc<RouterInner<S>> containing a PathRouter and catch-all fallback; PathRouter stores endpoints in a vector indexed by RouteId and matches paths through matchit. — [axum/src/routing/mod.rs#L75-L102](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L75-L102) [axum/src/routing/path_router.rs#L16-L19](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L16-L19) [axum/src/routing/path_router.rs#L357-L386](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L357-L386)
- axum-extra gates utilities behind Cargo features, while axum-macros is a proc-macro crate built with syn, quote, and proc-macro2. — [axum-extra/src/lib.rs#L8-L34](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/lib.rs#L8-L34) [axum-macros/Cargo.toml#L17-L32](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/Cargo.toml#L17-L32)
- examples/Cargo.toml defines a separate workspace; example binaries bind listeners and pass application routers to axum::serve, with database and session ownership established inside those binaries. — [examples/Cargo.toml#L1-L8](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/Cargo.toml#L1-L8) [examples/sqlx-postgres/src/main.rs#L38-L60](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/sqlx-postgres/src/main.rs#L38-L60) [examples/oauth/src/main.rs#L51-L80](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L51-L80)
- CI specifies locked workspace tests and all-target, all-feature Clippy checks for both workspaces, plus formatting, documentation, feature, MSRV, ARM, and selected WASM checks. — [.github/workflows/CI.yml#L15-L49](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L15-L49) [.github/workflows/CI.yml#L51-L64](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L51-L64) [.github/workflows/CI.yml#L83-L145](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L83-L145) [.github/workflows/CI.yml#L163-L197](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L163-L197)
- Release-plz runs on main and v0.8.x for the tokio-rs owner; configuration disables release-on-every-commit behavior and automatic changelog updates, while README warns that main contains forthcoming 0.9 breaking changes. — [.github/workflows/release-plz.yml#L3-L18](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/release-plz.yml#L3-L18) [release-plz.toml#L1-L12](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/release-plz.toml#L1-L12) [axum/README.md#L26-L31](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/README.md#L26-L31)

## Feature catalog

The principal user-facing surface is Rust APIs for routing, typed request extraction, middleware composition, and response generation. Feature flags add protocol and serialization capabilities without making every dependency mandatory. Optional crates extend the surface with cookies, typed routes, streaming formats, and compile-time diagnostics. The inspected examples demonstrate authentication, database access, forms, validation, static assets, TLS, and live connections.
- Router supports handler routes and arbitrary infallible services; repeated registration of different methods at an existing path merges MethodRouter endpoints. — [axum/src/routing/mod.rs#L183-L207](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L183-L207) [axum/src/routing/path_router.rs#L35-L59](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L35-L59)
- MethodRouter dispatches GET, POST, OPTIONS, PATCH, PUT, DELETE, TRACE, CONNECT, QUERY, and HEAD; HEAD falls back to GET, and unmatched methods use a fallback with configurable Allow-header handling. — [axum/src/routing/method_routing.rs#L1200-L1256](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/method_routing.rs#L1200-L1256)
- Typed inputs include Path, Query, Json, Form, State, and Multipart; Query deserializes URI parameters, Json requires an application/json-compatible content type, and Multipart parses a boundary before exposing fields. — [axum/src/lib.rs#L76-L95](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/lib.rs#L76-L95) [axum/src/extract/query.rs#L78-L84](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/extract/query.rs#L78-L84) [axum/src/json.rs#L99-L113](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L99-L113) [axum/src/extract/multipart.rs#L68-L80](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/extract/multipart.rs#L68-L80)
- Handlers return IntoResponse values, including Result branches and Json; Json serialization sets application/json on success and returns a 500 text response if serialization fails. — [axum-core/src/response/into_response.rs#L115-L150](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/response/into_response.rs#L115-L150) [axum/src/json.rs#L197-L230](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L197-L230)
- Middleware can wrap routers, method routers, or individual handlers; the documented Tower ecosystem supplies tracing, CORS, compression, request IDs, and timeouts, and from_fn exposes Next::run for async middleware. — [axum/src/docs/middleware.md#L12-L59](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/docs/middleware.md#L12-L59) [axum/src/middleware/from_fn.rs#L336-L349](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/middleware/from_fn.rs#L336-L349)
- WebSocketUpgrade supports HTTP/1 upgrade and HTTP/2 CONNECT handshakes; Sse converts event streams to text/event-stream responses and can add keep-alive events. — [axum/src/extract/ws.rs#L427-L449](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/extract/ws.rs#L427-L449) [axum/src/extract/ws.rs#L497-L539](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/extract/ws.rs#L497-L539) [axum/src/response/sse.rs#L102-L136](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/response/sse.rs#L102-L136)
- axum-extra offers private and signed cookies, typed headers and routing, file streams, attachments, Protobuf, JSON Lines, cached extraction, and rejection adapters; macros add TypedPath, FromRef, and debug_handler support. — [axum-extra/src/lib.rs#L8-L34](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/lib.rs#L8-L34) [axum-extra/src/routing/typed.rs#L84-L95](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/routing/typed.rs#L84-L95) [axum-macros/src/lib.rs#L575-L583](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/lib.rs#L575-L583) [axum-macros/src/lib.rs#L712-L715](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/lib.rs#L712-L715)
- Examples expose JWT authorization, Discord OAuth login, PostgreSQL queries and user persistence, validated forms, static-file service variants, and Rustls TLS connections. — [examples/jwt/src/main.rs#L68-L76](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/jwt/src/main.rs#L68-L76) [examples/oauth/src/main.rs#L59-L65](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L59-L65) [examples/diesel-postgres/src/main.rs#L79-L89](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L79-L89) [examples/low-level-rustls/src/main.rs#L34-L60](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/low-level-rustls/src/main.rs#L34-L60)

## Data flow

Incoming connections are converted into per-connection services, and incoming HTTP bodies are normalized before routing. Path matching enriches request extensions, method dispatch selects an endpoint, and handler adapters construct typed arguments in sequence. Response conversion provides the common output boundary for successful values and rejections. Durable data, session storage, and file writes are owned by example applications rather than the routing library.
- handle_connection waits for make_service readiness, calls it with IncomingStream, maps Hyper Incoming bodies into axum Body, and wraps the resulting Tower service with TowerToHyperService. — [axum/src/serve/mod.rs#L814-L828](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L814-L828)
- PathRouter preserves OriginalUri when enabled, matches uri.path(), installs MatchedPath and URL parameters, then dispatches the indexed endpoint; a missing path returns the request and state to Router's fallback. — [axum/src/routing/path_router.rs#L280-L325](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L280-L325) [axum/src/routing/mod.rs#L445-L454](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L445-L454)
- Handler::call splits the request, extracts all preceding arguments from mutable Parts, reconstructs the request for the last extractor, and returns immediately on any rejection before invoking the handler. — [axum/src/handler/mod.rs#L227-L255](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/handler/mod.rs#L227-L255)
- Json extraction validates content type, delegates buffering to Bytes::from_request, deserializes with serde_path_to_error, and calls deserializer.end() to reject trailing data. — [axum/src/json.rs#L99-L113](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L99-L113) [axum/src/json.rs#L164-L193](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L164-L193) [axum-core/src/extract/request_parts.rs#L101-L115](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/extract/request_parts.rs#L101-L115)
- State<InnerState> derives application substates through FromRef<OuterState>; Router::with_state distributes supplied state to its path router and catch-all fallback. — [axum/src/extract/state.rs#L303-L315](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/extract/state.rs#L303-L315) [axum/src/routing/mod.rs#L436-L442](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L436-L442)
- The key-value example transforms a path capture and body bytes into a HashMap insertion under a write lock; reads clone stored Bytes under a read lock and return 404 when absent. — [examples/key-value-store/src/main.rs#L84-L105](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/key-value-store/src/main.rs#L84-L105)
- Diesel create_user deserializes NewUser, acquires a pooled connection, inserts values inside interact, retrieves the returned User, and serializes it as Json; the migration defines the corresponding users table. — [examples/diesel-postgres/src/main.rs#L45-L50](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L45-L50) [examples/diesel-postgres/src/main.rs#L92-L107](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L92-L107) [examples/diesel-postgres/migrations/2023-03-14-180127_add_users/up.sql#L2-L6](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/migrations/2023-03-14-180127_add_users/up.sql#L2-L6)
- PrivateCookieJar obtains a key from state, retains only successfully decrypted request cookies, and writes jar changes into response headers through IntoResponseParts. — [axum-extra/src/extract/cookie/private.rs#L125-L164](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/extract/cookie/private.rs#L125-L164) [axum-extra/src/extract/cookie/private.rs#L273-L284](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/extract/cookie/private.rs#L273-L284)

## Behavior traces

The inspected flows span library execution and concrete example applications. Server startup proceeds from application construction to listener acceptance and Hyper connection execution. Request processing includes conditional rejection before business logic, while authentication and persistence examples introduce additional state and network boundaries. These traces describe source execution order; none were exercised at runtime.
- Startup: the key-value main initializes tracing, creates SharedState, composes routes and middleware, supplies state, binds 127.0.0.1:3000, and awaits axum::serve; Serve::run then repeatedly accepts and calls handle_connection. — [examples/key-value-store/src/main.rs#L32-L81](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/key-value-store/src/main.rs#L32-L81) [axum/src/serve/mod.rs#L527-L550](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L527-L550)
- Request dispatch: Router::call_with_state calls PathRouter::call_with_state, which matches the path and calls MethodRouter::call_with_state; the selected endpoint becomes a Route, and Handler::call extracts arguments before calling the async function. — [axum/src/routing/mod.rs#L445-L454](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L445-L454) [axum/src/routing/path_router.rs#L295-L320](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L295-L320) [axum/src/routing/method_routing.rs#L1200-L1216](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/method_routing.rs#L1200-L1216) [axum/src/handler/mod.rs#L238-L255](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/handler/mod.rs#L238-L255)
- Key-value write/read: POST /{key} selects kv_set with DefaultBodyLimit disabled and a 5,120,000-byte RequestBodyLimitLayer; kv_set inserts bytes, and subsequent GET /{key} uses kv_get's compressed response or 404 branch. — [examples/key-value-store/src/main.rs#L46-L59](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/key-value-store/src/main.rs#L46-L59) [examples/key-value-store/src/main.rs#L91-L105](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/key-value-store/src/main.rs#L91-L105)
- JWT flow: POST /authorize extracts AuthPayload, rejects empty or incorrect demonstration credentials, creates Claims, encodes a token, and returns AuthBody; GET /protected extracts a Bearer header and decodes Claims with Validation::default before protected runs. — [examples/jwt/src/main.rs#L79-L106](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/jwt/src/main.rs#L79-L106) [examples/jwt/src/main.rs#L124-L140](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/jwt/src/main.rs#L124-L140)
- OAuth initiation: discord_auth creates an identify-scoped authorization URL and random CSRF token, stores the token in MemoryStore, sets a Secure/HttpOnly/SameSite=Lax session cookie, and redirects to Discord. — [examples/oauth/src/main.rs#L153-L183](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L153-L183)
- OAuth callback: login_authorized calls csrf_token_validation_workflow, which loads and destroys the old session before comparing state; it then exchanges the code, fetches Discord user JSON, stores a new user session, sets its cookie, and redirects home. — [examples/oauth/src/main.rs#L224-L262](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L224-L262) [examples/oauth/src/main.rs#L265-L317](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L265-L317)
- Persistence startup/action: Diesel main builds a pool and runs embedded pending migrations before binding; POST /user/create invokes create_user's insert-and-return path, while GET /user/list loads Users through another interact closure. — [examples/diesel-postgres/src/main.rs#L62-L89](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L62-L89) [examples/diesel-postgres/src/main.rs#L92-L119](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L92-L119)
- Graceful shutdown: the signal task drops signal_tx, the accept loop exits on channel closure, connection tasks call Hyper graceful_shutdown, and the server waits for close_tx.closed(); a connection age limit can separately initiate shutdown and enforce a grace deadline. — [axum/src/serve/mod.rs#L678-L719](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L678-L719) [axum/src/serve/mod.rs#L847-L887](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L847-L887)

## Testing signals

Tests and CI were inspected, not executed; test existence is not evidence of a passing result. The inspected suite combines Tokio runtime tests, direct Tower service calls, real HTTP/WebSocket clients, and nightly compile-time fixtures. Assertions cover several important protocol and rejection behaviors, while individual example tests have narrower scopes. This is a bounded assessment without measured coverage or live integration verification.
- CI declares stable/beta locked all-feature, all-target tests for both workspaces, a separate nightly macro job, and Rust 1.80 tests after minimal-version dependency selection; these configurations were read, not run. — [.github/workflows/CI.yml#L83-L145](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L83-L145)
- The internal #[crate::test] helper expands to #[tokio::test] and generates an additional nest_service variant when a test contains matching nest calls; TestClient launches an ephemeral localhost server and uses reqwest with redirects disabled. — [axum-macros/src/axum_test.rs#L5-L43](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/axum_test.rs#L5-L43) [axum/src/test_helpers/test_client.rs#L11-L48](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/test_helpers/test_client.rs#L11-L48)
- Routing tests assert inherited versus overridden nested fallbacks; HEAD tests use Router::oneshot directly and assert preserved headers with an empty response body for handlers and services. — [axum/src/routing/tests/fallback.rs#L84-L109](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/tests/fallback.rs#L84-L109) [axum/src/routing/tests/get_to_head.rs#L7-L34](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/tests/get_to_head.rs#L7-L34) [axum/src/routing/tests/get_to_head.rs#L41-L68](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/tests/get_to_head.rs#L41-L68)
- Json tests assert successful deserialization, 415 without JSON content type, accepted +json media types, 400 for syntax/trailing-data errors, and 422 with a field path for invalid typed data. — [axum/src/json.rs#L242-L308](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L242-L308) [axum/src/json.rs#L312-L332](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L312-L332) [axum/src/json.rs#L351-L367](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/json.rs#L351-L367)
- Server tests use paused Tokio time and duplex IO to assert stalled-header closure; graceful_shutdown_completes_inflight_request holds a handler open, signals shutdown, then checks that its response completes before the server resolves. — [axum/src/serve/mod.rs#L1229-L1283](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L1229-L1283) [axum/src/serve/mod.rs#L1333-L1400](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L1333-L1400)
- Macro UI tests use trybuild pass/fail fixtures only on nightly, become a no-op on other toolchains, and accept AXUM_TEST_ONLY; inspected failures exercise wrong extractor order and a non-Send future. — [axum-macros/src/lib.rs#L796-L827](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/lib.rs#L796-L827) [axum-macros/tests/debug_handler/fail/wrong_order.rs#L1-L10](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/tests/debug_handler/fail/wrong_order.rs#L1-L10) [axum-macros/tests/debug_handler/fail/not_send.rs#L1-L9](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/tests/debug_handler/fail/not_send.rs#L1-L9)
- The WebSocket example tests one text echo through a real tokio-tungstenite connection and through mocked Sink/Stream channels; the SSE example integration test takes one event and asserts its data is hi!. — [examples/testing-websockets/src/main.rs#L103-L146](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/testing-websockets/src/main.rs#L103-L146) [examples/sse/src/main.rs#L99-L126](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/sse/src/main.rs#L99-L126)
- Form tests check GET markup and one POST response; validator tests check missing, empty, short, and valid names; the inspected static-file test checks one root-path fallback returning index HTML with 404, rather than every service variant. — [examples/form/src/main.rs#L84-L123](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/form/src/main.rs#L84-L123) [examples/validator/src/main.rs#L115-L166](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/validator/src/main.rs#L115-L166) [examples/static-file-server/src/tests.rs#L8-L27](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/static-file-server/src/tests.rs#L8-L27) [examples/static-file-server/src/main.rs#L30-L38](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/static-file-server/src/main.rs#L30-L38)

## Risk map

These findings are source observations and explicitly identified hypotheses, not confirmed vulnerabilities. The main boundaries worth reviewing are request resource limits, example authentication, network integrations, HTML generation, database startup, and upload IO. Framework safeguards have conditions: extractor-local limits do not cover every body consumer, and middleware placement affects which requests receive protection. Example code should be assessed in its deployment context before reuse.
- DefaultBodyLimit bounds cooperating extractors to 2,097,152 bytes by default, but direct body consumption bypasses it; the upload example's Request-based path streams the body without applying that extractor-local limit. — [axum-core/src/extract/default_body_limit.rs#L7-L24](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/extract/default_body_limit.rs#L7-L24) [axum-core/src/ext_traits/request.rs#L316-L331](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/ext_traits/request.rs#L316-L331) [examples/stream-to-file/src/main.rs#L52-L56](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/stream-to-file/src/main.rs#L52-L56)
- JWT authorization is demonstration logic with fixed accepted credentials and a fixed expiry; KEYS reads JWT_SECRET lazily with expect, so missing configuration panics when key use first initializes it. — [examples/jwt/src/main.rs#L53-L56](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/jwt/src/main.rs#L53-L56) [examples/jwt/src/main.rs#L86-L103](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/jwt/src/main.rs#L86-L103)
- OAuth explicitly warns against its MemoryStore in production; User extraction panics for unexpected cookie-header errors and unwraps session loading, creating request-path failure points despite normal missing-session redirects. — [examples/oauth/src/main.rs#L51-L52](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L51-L52) [examples/oauth/src/main.rs#L336-L357](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L336-L357)
- The form and validator handlers interpolate user-provided strings directly into Html responses without an escaping transform in those handlers; validation in the latter checks name length. — [examples/form/src/main.rs#L69-L71](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/form/src/main.rs#L69-L71) [examples/validator/src/main.rs#L49-L56](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/validator/src/main.rs#L49-L56)
- Upload IO validates a single normal path component, then joins it beneath a working-directory-relative uploads directory and uses File::create; multipart iteration exits on next_field errors and still returns its normal redirect. — [examples/stream-to-file/src/main.rs#L21-L36](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/stream-to-file/src/main.rs#L21-L36) [examples/stream-to-file/src/main.rs#L88-L99](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/stream-to-file/src/main.rs#L88-L99) [examples/stream-to-file/src/main.rs#L108-L142](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/stream-to-file/src/main.rs#L108-L142)
- Database examples require external services: Diesel runs migrations before listening, tokio-postgres uses NoTls, and SQLx/Diesel internal_error expose error strings in 500 responses. — [examples/diesel-postgres/src/main.rs#L70-L76](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L70-L76) [examples/tokio-postgres/src/main.rs#L28-L32](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/tokio-postgres/src/main.rs#L28-L32) [examples/sqlx-postgres/src/main.rs#L104-L108](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/sqlx-postgres/src/main.rs#L104-L108) [examples/diesel-postgres/src/main.rs#L124-L128](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L124-L128)
- Middleware placement is a coupling hotspot: Router::layer wraps previously added routes and repeated layers run outermost-last, whereas ServiceBuilder composes a different ordering; the error example depends on TraceLayer enclosing log_app_errors. — [axum/src/docs/middleware.md#L61-L119](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/docs/middleware.md#L61-L119) [axum/src/docs/middleware.md#L121-L145](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/docs/middleware.md#L121-L145) [examples/error-handling/src/main.rs#L61-L85](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/error-handling/src/main.rs#L61-L85)
- Dependency policy excludes unpublished packages, disables unmaintained-advisory reporting, and permits selected duplicate trees; CI marks the advisories matrix entry continue-on-error, so that job alone does not make advisories a blocking gate. — [deny.toml#L1-L6](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/deny.toml#L1-L6) [deny.toml#L17-L26](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/deny.toml#L17-L26) [.github/workflows/CI.yml#L147-L161](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L147-L161)

## Extension points

Extensions are expressed through Rust traits, router builders, Cargo features, and generated implementations. Applications can add typed request inputs and outputs without changing the router internals. Tower services and layers supply middleware composition, while Listener and Executor customize serving within the Tokio/Hyper architecture. axum-extra and axum-macros provide additional integration points for typed routes, cookies, and generated extraction.
- Implement FromRequestParts<S> for metadata-only inputs or FromRequest<S> for body-consuming inputs; both define an IntoResponse rejection and receive application state. — [axum-core/src/extract/mod.rs#L41-L90](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/extract/mod.rs#L41-L90)
- Implement IntoResponse for domain outputs and errors; its Result implementation converts either branch, allowing application errors to remain HTTP responses rather than Tower service failures. — [axum-core/src/response/into_response.rs#L115-L150](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/response/into_response.rs#L115-L150) [axum/src/docs/error_handling.md#L25-L46](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/docs/error_handling.md#L25-L46)
- Router::route_service accepts cloneable infallible Tower services with IntoResponse outputs, while PathRouter merges method registrations at the same path. — [axum/src/routing/mod.rs#L191-L207](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L191-L207) [axum/src/routing/path_router.rs#L35-L59](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L35-L59)
- Tower Layer can wrap individual handlers through Handler::layer; from_fn middleware receives a Next continuation that executes the remaining service stack. — [axum/src/handler/mod.rs#L189-L203](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/handler/mod.rs#L189-L203) [axum/src/middleware/from_fn.rs#L306-L309](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/middleware/from_fn.rs#L306-L309) [axum/src/middleware/from_fn.rs#L336-L349](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/middleware/from_fn.rs#L336-L349)
- FromRef connects aggregate application state to substates; the OAuth example independently extracts MemoryStore and BasicClient from AppState, and axum-macros exposes a FromRef derive. — [axum/src/extract/state.rs#L303-L315](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/extract/state.rs#L303-L315) [examples/oauth/src/main.rs#L83-L98](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/oauth/src/main.rs#L83-L98) [axum-macros/src/lib.rs#L712-L715](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/lib.rs#L712-L715)
- TypedPath links a handler's first argument to a route, derives capture-compatible extraction and percent-encoded Display output, and supports custom rejections; vpath! separately validates static path syntax at compile time. — [axum-extra/src/routing/typed.rs#L22-L44](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/routing/typed.rs#L22-L44) [axum-extra/src/routing/typed.rs#L84-L95](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/routing/typed.rs#L84-L95) [axum-extra/src/routing/typed.rs#L124-L150](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/routing/typed.rs#L124-L150) [axum-extra/src/routing/mod.rs#L28-L53](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/src/routing/mod.rs#L28-L53)
- Custom Listener implementations choose IO/address types and own accept-error retry behavior; ListenerExt adds connection limits, while Serve::with_executor substitutes an Executor returning Tokio JoinHandles. — [axum/src/serve/listener.rs#L15-L30](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/listener.rs#L15-L30) [axum/src/serve/listener.rs#L73-L90](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/listener.rs#L73-L90) [axum/src/serve/mod.rs#L345-L366](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L345-L366) [axum/src/serve/mod.rs#L499-L509](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/serve/mod.rs#L499-L509)
- FromRequest derives accept container-level via, rejection, and state attributes; expansion chooses explicit state or infers it from fields and delegation, providing a generated-wrapper extension path. — [axum-macros/src/from_request/mod.rs#L93-L135](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/from_request/mod.rs#L93-L135) [examples/error-handling/src/main.rs#L136-L149](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/error-handling/src/main.rs#L136-L149)

## Contributor handoff

Start future work from the pinned source and the owning crate rather than assuming released behavior matches main. Keep changes aligned with crate boundaries, feature gates, and the distinction between library contracts and runnable examples. Tests and CI were inspected, not executed; future execution needs its own authorization and reported results. This brief is bounded and does not establish whole-repository coverage, live integration health, or confirmed vulnerabilities.
- Read README's branch warning before using released API assumptions: main targets 0.9 breaking changes even though the inspected axum manifest declares version 0.8.9. — [axum/README.md#L26-L31](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/README.md#L26-L31) [axum/Cargo.toml#L1-L7](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/Cargo.toml#L1-L7)
- Choose the owning boundary first: reusable extractor/response contracts belong in axum-core where possible; optional utility exposure must follow axum-extra's feature gates rather than unconditional dependencies. — [axum-core/src/lib.rs#L1-L9](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/lib.rs#L1-L9) [axum-extra/Cargo.toml#L37-L94](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/Cargo.toml#L37-L94)
- For dispatch edits, read Router, PathRouter, MethodRouter, and Handler together; preserve path metadata installation, HEAD-to-GET selection, rejection short-circuiting, and state delivery. — [axum/src/routing/mod.rs#L445-L454](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/mod.rs#L445-L454) [axum/src/routing/path_router.rs#L280-L320](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/path_router.rs#L280-L320) [axum/src/routing/method_routing.rs#L1238-L1256](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/routing/method_routing.rs#L1238-L1256) [axum/src/handler/mod.rs#L238-L255](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum/src/handler/mod.rs#L238-L255)
- Body-limit edits require coordinated documentation and implementation review: RequestExt explicitly points to default_body_limit.rs and extract.md when changing DEFAULT_LIMIT, and direct consumers need separate scrutiny. — [axum-core/src/ext_traits/request.rs#L316-L331](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/ext_traits/request.rs#L316-L331) [axum-core/src/extract/default_body_limit.rs#L7-L24](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-core/src/extract/default_body_limit.rs#L7-L24)
- Keep example checks in their workspace: CI uses --manifest-path examples/Cargo.toml separately from the root, and example binaries may connect to databases or run startup migrations. — [examples/Cargo.toml#L1-L5](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/Cargo.toml#L1-L5) [.github/workflows/CI.yml#L83-L100](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L83-L100) [examples/diesel-postgres/src/main.rs#L62-L76](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/examples/diesel-postgres/src/main.rs#L62-L76)
- Tests and CI were inspected, not executed in this investigation; for authorized future validation, use a filtered affected-package test first and follow CI's locked workspace tests, formatting, and all-feature Clippy commands as scope requires. — [.github/workflows/CI.yml#L29-L32](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L29-L32) [.github/workflows/CI.yml#L99-L100](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L99-L100) [CONTRIBUTING.md#L115-L126](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/CONTRIBUTING.md#L115-L126)
- Macro diagnostic work needs nightly trybuild coverage, optionally narrowed with AXUM_TEST_ONLY; stable/beta runs skip that harness, and debug_handler itself emits checks only with debug_assertions enabled. — [axum-macros/src/lib.rs#L575-L583](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/lib.rs#L575-L583) [axum-macros/src/lib.rs#L796-L827](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-macros/src/lib.rs#L796-L827) [.github/workflows/CI.yml#L103-L119](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.github/workflows/CI.yml#L103-L119)
- Preserve compatibility conventions: workspace lints forbid unsafe code, Clippy disallows BoxCloneService in favor of BoxCloneSyncService, and axum-extra deliberately retains its older serde_html_form behavior for deprecated Query/Form migration support. — [Cargo.toml#L8-L14](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/Cargo.toml#L8-L14) [.clippy.toml#L1-L4](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/.clippy.toml#L1-L4) [axum-extra/Cargo.toml#L125-L130](https://github.com/tokio-rs/axum/blob/f8b02f22cf10bee707bda19b58265b9e33677535/axum-extra/Cargo.toml#L125-L130)

Source repository: https://github.com/tokio-rs/axum
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/axum.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
