Help us improve
Share bugs, ideas, or general feedback.
From beagle-rust
Reviews axum web framework code for routing patterns, extractor usage, middleware, state management, and error handling. Covers axum 0.7+ patterns including State, Path, Query, Json extractors.
npx claudepluginhub existential-birds/beagle --plugin beagle-rustHow this skill is triggered — by the user, by Claude, or both
Slash command
/beagle-rust:axum-code-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
1. **Check Cargo.toml** — Note axum version (0.6 vs 0.7+ have different patterns), Rust edition (2021 vs 2024), tower, tower-http features. Edition 2024 changes RPIT lifetime capture in handler return types and removes the need for `async-trait` in custom extractors.
Provides Axum 0.8.0–0.8.5 knowledge: {param} path syntax, native async extractors, Utf8Bytes WebSockets, HTTP/2 WS, NoContent. Load before 0.8+ Axum work.
Analyzes Rust projects on Cargo.toml detection: identifies binaries/libs/workspaces, extracts patterns in async (Tokio/async-std), errors (thiserror/anyhow), web (Axum/Actix-web/Rocket), testing, logging.
Reviews Rust code changes found via git diff, runs clippy, and optionally spawns parallel agents for deeper analysis.
Share bugs, ideas, or general feedback.
async-trait in custom extractors.State<T>, not global mutable stateIntoResponse implementations, error typesRun in order. Do not write a finding until the step that applies has passed.
Version and edition on disk — Pass when: You have read the relevant Cargo.toml (crate or workspace root) and can state axum (and related tower/tower-http) versions and Rust edition. Then apply 0.6 vs 0.7+ or Edition 2024–specific checklist items only when that file supports them.
Per-finding evidence — Pass when: Each issue cites [FILE:LINE] from the current tree for the handler, router, layer, or type under review (not from memory, docs-only, or another branch).
Category check vs protocol — Pass when: For the finding type (routing conflict, extractor order, error leak, middleware order, etc.), you ran the matching checks from beagle-rust:review-verification-protocol (e.g. full handler signature for extractor order; surrounding error mapping before “raw error to client”). Then add the finding.
Output shape — Pass when: The report lines match Output Format below (severity + description).
Report findings as:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
| Issue Type | Reference |
|---|---|
| Route definitions, nesting, method routing | references/routing.md |
| State, Path, Query, Json, body extractors | references/extractors.md |
| Tower middleware, layers, error handling | references/middleware.md |
/api/users, /api/orders).get(), .post(), not .route() with manual method matching)Json, Form, Bytes) are the LAST parameterState<T> requires T: Clone — typically Arc<AppState> or direct Clone derivePath<T> parameter types match the route definitionQuery<T> fields are Option for optional query params with #[serde(default)]FromRequestParts (not body) or FromRequest (body)async fn in trait impls (no #[async_trait] needed for FromRequest/FromRequestParts)State<T>, not global mutable staticsClone derived or manually implemented on state typeLazyLock from std (not once_cell::sync::Lazy or lazy_static!)IntoResponse for proper HTTP error codesResult<impl IntoResponse, AppError> pattern used for handlers-> impl IntoResponse capture all in-scope lifetimes by default; use + use<> to opt out of capturing request lifetimes when returning owned datatower-http used for common concerns (CORS, compression, tracing, timeout)#[async_trait] can migrate to native async fn in trait implsState<T> (race conditions)sqlx::Error returned to client)async-trait still used for FromRequest/FromRequestParts when native async fn works.get(), .post()tower-http::trace for request loggingonce_cell::sync::Lazy or lazy_static! used where std::sync::LazyLock workstower-http layers for common concernsutoipa or aide#[axum::debug_handler] on handlers — Debugging aid that improves compile error messagesExtension<T> for middleware-injected data — Valid pattern for request-scoped valuesimpl IntoResponse from handlers — More flexible than concrete typesRouter::new() per module, merged in main — Standard organization patternServiceBuilder for layer composition — Tower pattern, not over-engineeringaxum::serve with TcpListener — Standard axum 0.7+ server setupasync fn in FromRequest/FromRequestParts impls — async-trait crate no longer needed (stable since Rust 1.75)+ use<'a> on handler return types — Edition 2024 precise capture syntax for RPITstd::sync::LazyLock for shared static state — Replaces once_cell/lazy_static (stable since Rust 1.80)Complete Gates (before reporting findings) and load beagle-rust:review-verification-protocol for category-specific checks before any issue is final.