aide
A code-first Rust library that generates OpenAPI 3.1 documentation directly from your Axum routes and types.
Repository Health
Technical Analysis
Aide is a Rust library for generating OpenAPI 3.1 documentation without hand-writing YAML or JSON specs. Instead of maintaining a separate spec file, you annotate your existing Axum handlers and types, and Aide derives the documentation from the code itself: request/response schemas come from schemars::JsonSchema implementations on your types, and route metadata comes from the ApiRouter/api_route builder pattern that mirrors Axum’s own API almost one-to-one.
The library was rewritten from a macro-heavy design (pre-0.5) to a function- and builder-based approach specifically so that rustfmt and IDE code completion keep working, and so documentation stays traceable in ordinary source code rather than hidden behind macro expansion. It ships optional feature flags for serving interactive docs (Swagger UI, Redoc, Scalar) directly from the same binary, and currently targets Axum as its primary framework integration, having dropped actix-web support after 0.4.
What You Get
ApiRouterandApiMethodRouter— drop-in wrappers aroundaxum::Router/MethodRouterthat track which routes should appear in the generated spec viaapi_route- Automatic schema generation for request/response bodies via the
OperationInput/OperationOutputtraits combined withschemars::JsonSchema - A declarative
transformbuilder API for attaching descriptions, examples, and metadata to operations, parameters, and responses without macros - Full typed OpenAPI 3.1 object model (
openapi::OpenApi,Operation,Schema,SecurityScheme, etc.) usable directly as Rust structs - Optional built-in UI feature flags (
redoc,swagger,scalar) to serve interactive API documentation from the same server - A thread-local error-handling hook (
aide::generate::on_error) for surfacing documentation-generation issues instead of silently dropping them
Common Use Cases
- Generating and serving an OpenAPI 3.1 spec for a Rust/Axum backend so frontend or third-party consumers get accurate, always-current API docs
- Adding interactive Swagger UI, Redoc, or Scalar documentation pages to an existing Axum service with minimal route changes
- Deriving request/response JSON Schemas automatically from existing
serde-derived Rust types instead of maintaining them by hand - Migrating a Rust API off manually-maintained OpenAPI YAML/JSON onto a code-first, compile-time-checked documentation workflow
Under The Hood
Architecture
Aide’s core is a thread-local GenContext (see crates/aide/src/generate.rs) that accumulates schemas and errors during a documentation-generation pass, read via aide::generate::in_context. The public surface is split across openapi (a full typed OpenAPI 3.1 object model — openapi.rs, operation.rs, schema.rs, security_scheme.rs, etc.), operation/transform (the builder-pattern API used to attach metadata, in operation.rs and the 1500+ line transform.rs), and a framework adapter under axum/ (mod.rs, routing/mod.rs, routing/typed.rs, inputs.rs, outputs.rs) that wraps axum::Router with ApiRouter so only routes added via api_route are collected for the spec. This is a clean adapter/wrapper architecture: the framework integration layer is feature-gated and isolated from the OpenAPI type model, so adding support for another framework would mean writing a new adapter module without touching the spec types.
Tech Stack
The crate is pure Rust (Cargo workspace with aide and a proc-macro crate aide-macros built on syn/quote/darling). Core dependencies are schemars 1.0 (JSON Schema generation, with indexmap2 support), serde/serde_json for spec (de)serialization, indexmap for order-preserving maps, and thiserror for its Error type. Framework integration is entirely optional via Cargo features: axum 0.8 and axum-extra 0.12 are pulled in only behind feature flags (axum, axum-extra, plus many narrower flags like axum-multipart, axum-ws, axum-extra-typed-routing), and interactive-docs UIs (redoc, swagger, scalar) are similarly opt-in. No default features are enabled, keeping the base dependency footprint minimal.
Code Quality
Tests are embedded as #[cfg(test)] modules directly in the source files they cover (operation.rs, transform.rs, openapi/openapi.rs, openapi/schema.rs, axum/mod.rs) rather than a separate tests/ directory — a reasonable choice for a library whose logic is mostly builder methods and trait impls. CI (.github/workflows/rust.yml) runs cargo fmt --check, cargo hack check --each-feature (verifying every feature flag compiles in isolation, important given how many there are), a full build, and cargo test. lib.rs enables #![warn(clippy::pedantic, missing_docs, unreachable_pub, rust_2018_idioms)], meaning public items are required to be documented and lints are held to a stricter-than-default bar, with specific pedantic lints explicitly allowed where they’d be noise.
API Design
The library is explicitly designed to mirror Axum’s own API as closely as possible — ApiRouter::api_route reads like Router::route, and the axum::routing re-exports (get, post, etc.) have direct counterparts in aide::axum::routing — so adopting it is largely a search-and-replace on an existing Axum app rather than a rewrite. Documentation is attached via composable builder functions (transform) rather than annotation macros, which keeps things rustfmt- and IDE-completion-friendly, a tradeoff the maintainers document explicitly in lib.rs as the reason for the pre-0.5 rewrite. The crate favors surfacing generation errors (documented as deliberately choosing false positives over silently swallowing real ones) over failing silently, which is unusual ergonomic honesty for this kind of tooling.