Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
claude-dev-suite avatar

Axum

  • 36 installs
  • 27 repo stars
  • Updated July 17, 2026
  • claude-dev-suite/claude-dev-suite

Build async Rust web APIs with Axum using routing, handlers, extractors, tower middleware, and shared state.

About

Reference for the Axum Rust web framework covering routing, handlers, extractors, tower middleware, and state. A developer uses it when building ergonomic async Rust APIs on Tokio.

  • Router, handlers, and extractor patterns
  • Tower middleware and shared state

Axum by the numbers

  • 36 all-time installs (skills.sh)
  • Ranked #79 of 121 Rust skills by installs in the Skillselion catalog
  • Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill axum

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs36
repo stars27
Last updatedJuly 17, 2026
Repositoryclaude-dev-suite/claude-dev-suite

What it does

Build async Rust web APIs with Axum using routing, handlers, extractors, tower middleware, and shared state.

Files

SKILL.mdMarkdownGitHub ↗

Axum Core Knowledge

Full Reference: See advanced.md for authentication middleware, WebSocket handling, graceful shutdown, and custom error types.
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: axum for comprehensive documentation.

Basic Setup

# Cargo.toml
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
tower-http = { version = "0.5", features = ["cors", "trace"] }
use axum::{routing::get, Router};

async fn hello() -> &'static str {
    "Hello, World!"
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(hello));

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

Routing

let app = Router::new()
    .route("/", get(index))
    .route("/users", get(list_users).post(create_user))
    .route("/users/:id", get(get_user).put(update_user).delete(delete_user));

// Nested Routes
let api_routes = Router::new()
    .route("/users", get(list_users));

let app = Router::new().nest("/api/v1", api_routes);

Extractors

use axum::extract::{Path, Query, Json, State};

// Path parameters
async fn get_user(Path(id): Path<u32>) -> String {
    format!("User {}", id)
}

// Query parameters
#[derive(Deserialize)]
struct Pagination { page: Option<u32>, per_page: Option<u32> }

async fn list_users(Query(pagination): Query<Pagination>) -> Json<Value> {
    Json(json!({ "page": pagination.page.unwrap_or(1) }))
}

// JSON body
async fn create_user(Json(payload): Json<CreateUser>) -> (StatusCode, Json<Value>) {
    (StatusCode::CREATED, Json(json!({ "name": payload.name })))
}

Application State

use std::sync::Arc;

struct AppState {
    db_pool: sqlx::PgPool,
}

async fn handler(State(state): State<Arc<AppState>>) -> String {
    // Use state.db_pool
}

let state = Arc::new(AppState { db_pool: pool });
let app = Router::new()
    .route("/", get(handler))
    .with_state(state);

Tower Middleware

use tower_http::{cors::CorsLayer, trace::TraceLayer};
use tower::ServiceBuilder;

let app = Router::new()
    .route("/", get(index))
    .layer(
        ServiceBuilder::new()
            .layer(TraceLayer::new_for_http())
            .layer(CorsLayer::permissive())
    );

Health Checks

async fn health() -> Json<Value> {
    Json(json!({ "status": "healthy" }))
}

async fn ready(State(state): State<Arc<AppState>>) -> Result<Json<Value>, StatusCode> {
    sqlx::query("SELECT 1")
        .execute(&state.db_pool)
        .await
        .map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;

    Ok(Json(json!({ "status": "ready" })))
}

When NOT to Use This Skill

  • Actix-web projects - Actix has more built-in features
  • Rocket projects - Rocket has compile-time route checking
  • Sync-only Rust code - Axum requires async runtime

Anti-Patterns

Anti-PatternWhy It's BadSolution
Not using Arc for stateExpensive clonesWrap state in Arc<AppState>
Blocking operations in handlersBlocks executorUse tokio::task::spawn_blocking
Missing error conversionCompiler errorsImplement IntoResponse for errors
Not using extractorsManual parsingUse Path, Query, Json extractors

Quick Troubleshooting

ProblemDiagnosisFix
"Handler doesn't implement Handler"Wrong signatureCheck extractor order and return type
Route not matchingConflicting routesOrder routes from specific to general
State not accessibleWrong state typeEnsure with_state() matches State<T>
Missing CORS headersNo layerAdd CorsLayer from tower-http

Production Checklist

  • [ ] Tracing/logging configured
  • [ ] CORS properly set up
  • [ ] Error handling with custom types
  • [ ] Health/readiness endpoints
  • [ ] Graceful shutdown
  • [ ] State management with Arc
  • [ ] Input validation

Reference Documentation

  • Extractors
  • Middleware

Related skills

Rustbackend

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.