Introdução
Quando se trata de desenvolvimento web em Rust, dois frameworks dominam o cenário: Axum e Actix Web. Ambos são maduros, performáticos e amplamente utilizados em produção, mas possuem filosofias de design bastante distintas. Se você está buscando o melhor framework web de Rust em 2026, esta comparação vai ajudá-lo a decidir.
Actix Web surgiu em 2017, inspirado no modelo de atores do Akka (Scala), e rapidamente se tornou o framework web mais popular de Rust — liderando benchmarks do TechEmpower por anos consecutivos. Ele oferece um ecossistema completo com middleware integrado, suporte a WebSocket e extensa documentação.
Axum foi lançado em 2021 pela equipe do Tokio e adota uma abordagem diferente: ao invés de criar abstrações próprias, ele se apoia inteiramente no ecossistema Tower (Service + Layer) e Hyper. O resultado é um framework mais enxuto, composável e que se integra nativamente com tudo que já existe no ecossistema Tokio.
Neste artigo, vamos comparar os dois em profundidade para ajudá-lo a escolher o melhor para seu próximo projeto.
Tabela Comparativa
| Característica | Axum | Actix Web |
|---|---|---|
| Primeira versão | 2021 | 2017 |
| Mantenedor | Equipe Tokio | Comunidade |
| Runtime | Tokio (obrigatório) | Tokio (padrão) |
| Modelo | Tower Services | Actor Model (parcial) |
| Middleware | Tower Layers | Transform / Middleware traits |
| Extractors | Genéricos via FromRequest | Trait FromRequest própria |
| WebSocket | Via axum::extract::ws | Integrado |
| Tipagem de rotas | Forte (compile-time) | Forte (compile-time) |
| Performance (TechEmpower) | Top 10 | Top 5 |
| Downloads (crates.io) | ~40M+ | ~55M+ |
| Curva de aprendizado | Moderada | Moderada |
Dependências no Cargo.toml
Para Axum:
[dependencies]
axum = "0.8"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tower-http = { version = "0.6", features = ["cors", "trace"] }
tracing = "0.1"
tracing-subscriber = "0.3"
Para Actix Web:
[dependencies]
actix-web = "4"
actix-rt = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
env_logger = "0.11"
log = "0.4"
Comparação de Código: API REST Básica
Vamos implementar a mesma API — um CRUD simples de tarefas — nos dois frameworks para comparar a ergonomia.
Hello World com Axum
use axum::{routing::get, Router};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(|| async { "Olá, Axum!" }));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
Hello World com Actix Web
use actix_web::{web, App, HttpServer, HttpResponse};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(|| async {
HttpResponse::Ok().body("Olá, Actix Web!")
}))
})
.bind("0.0.0.0:3000")?
.run()
.await
}
Endpoint com JSON e Extractor
Vamos criar um endpoint POST que recebe e retorna JSON.
Axum:
use axum::{routing::post, extract::Json, Router};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct CriarTarefa {
titulo: String,
descricao: Option<String>,
}
#[derive(Serialize)]
struct Tarefa {
id: u64,
titulo: String,
descricao: Option<String>,
concluida: bool,
}
async fn criar_tarefa(Json(payload): Json<CriarTarefa>) -> Json<Tarefa> {
let tarefa = Tarefa {
id: 1,
titulo: payload.titulo,
descricao: payload.descricao,
concluida: false,
};
Json(tarefa)
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/tarefas", post(criar_tarefa));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
Actix Web:
use actix_web::{web, App, HttpServer, HttpResponse};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct CriarTarefa {
titulo: String,
descricao: Option<String>,
}
#[derive(Serialize)]
struct Tarefa {
id: u64,
titulo: String,
descricao: Option<String>,
concluida: bool,
}
async fn criar_tarefa(payload: web::Json<CriarTarefa>) -> HttpResponse {
let tarefa = Tarefa {
id: 1,
titulo: payload.titulo.clone(),
descricao: payload.descricao.clone(),
concluida: false,
};
HttpResponse::Ok().json(tarefa)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/tarefas", web::post().to(criar_tarefa))
})
.bind("0.0.0.0:3000")?
.run()
.await
}
Estado Compartilhado
Axum utiliza State extractor integrado ao Router:
use axum::{extract::State, routing::get, Json, Router};
use std::sync::Arc;
use tokio::sync::RwLock;
type Db = Arc<RwLock<Vec<String>>>;
async fn listar(State(db): State<Db>) -> Json<Vec<String>> {
let dados = db.read().await;
Json(dados.clone())
}
#[tokio::main]
async fn main() {
let db: Db = Arc::new(RwLock::new(vec![]));
let app = Router::new()
.route("/itens", get(listar))
.with_state(db);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
Actix Web utiliza web::Data:
use actix_web::{web, App, HttpServer, HttpResponse};
use std::sync::RwLock;
struct AppState {
itens: RwLock<Vec<String>>,
}
async fn listar(data: web::Data<AppState>) -> HttpResponse {
let itens = data.itens.read().unwrap();
HttpResponse::Ok().json(itens.clone())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let state = web::Data::new(AppState {
itens: RwLock::new(vec![]),
});
HttpServer::new(move || {
App::new()
.app_data(state.clone())
.route("/itens", web::get().to(listar))
})
.bind("0.0.0.0:3000")?
.run()
.await
}
Middleware
Axum usa Tower Layers diretamente:
use axum::{Router, routing::get, middleware};
use tower_http::trace::TraceLayer;
use tower_http::cors::CorsLayer;
let app = Router::new()
.route("/", get(|| async { "ok" }))
.layer(TraceLayer::new_for_http())
.layer(CorsLayer::permissive());
Actix Web usa seu próprio sistema de middleware:
use actix_web::{App, HttpServer, web, middleware};
use actix_cors::Cors;
HttpServer::new(|| {
App::new()
.wrap(middleware::Logger::default())
.wrap(Cors::permissive())
.route("/", web::get().to(|| async { "ok" }))
})
Performance e Benchmarks
Ambos os frameworks são extremamente rápidos. Nos benchmarks do TechEmpower Framework Benchmarks (Round 22), ambos aparecem consistentemente entre os 10 mais rápidos do mundo, competindo com frameworks em C e C++.
Números aproximados (requisições/segundo em JSON serialization):
| Framework | Req/s (aprox.) |
|---|---|
| Actix Web | ~700.000+ |
| Axum | ~650.000+ |
| Express (Node.js) | ~80.000 |
| FastAPI (Python) | ~15.000 |
A diferença de performance entre Axum e Actix Web é marginal na maioria dos casos de uso reais. Actix Web historicamente tem uma leve vantagem em benchmarks sintéticos, mas na prática, o gargalo será o banco de dados, rede ou lógica de negócio — não o framework.
Ambos utilizam Tokio como runtime async por padrão, o que significa que a base de I/O assíncrono é a mesma. Para uma compreensão mais aprofundada do Tokio, veja nosso Guia Completo do Tokio.
Ecossistema e Comunidade
Axum
- Vantagem principal: integração total com o ecossistema Tower/Tokio
- Middleware do Tower funciona diretamente (rate limiting, timeout, compression)
- Mantido oficialmente pela equipe Tokio — garantia de compatibilidade
- Crescimento acelerado: já é o framework mais popular para novos projetos
- Excelente integração com
tracingpara observabilidade
Actix Web
- Vantagem principal: ecossistema próprio maduro e completo
actix-files,actix-cors,actix-session,actix-identity— tudo integrado- Comunidade grande e documentação extensa
- Usado em produção por empresas como Microsoft, Cloudflare e outras
Quando Escolher Cada Um
Escolha Axum quando:
- Você já usa ou planeja usar Tokio extensivamente
- Deseja máxima composabilidade com o ecossistema Tower
- Prefere um design mais idiomático e alinhado com traits padrão do Rust
- Está iniciando um projeto novo e quer seguir a tendência do ecossistema
- Precisa integrar com tonic (gRPC) — ambos são do ecossistema Tokio
Escolha Actix Web quando:
- Precisa de um ecossistema completo com muitos plugins oficiais
- Tem um projeto existente em Actix Web que funciona bem
- Precisa de WebSocket com API mais ergonômica out-of-the-box
- Valoriza documentação extensa e muitos exemplos disponíveis
- Precisa do máximo throughput em benchmarks sintéticos
Ambos são boas escolhas quando:
- Você precisa de uma API REST de alta performance
- Precisa de type safety em tempo de compilação
- Trabalha com equipes que conhecem Rust
Guia de Migração: Actix Web para Axum
Se você está considerando migrar de Actix Web para Axum, aqui estão os pontos principais:
1. Handlers
// Actix Web: retorna HttpResponse
async fn handler() -> HttpResponse {
HttpResponse::Ok().json(dados)
}
// Axum: retorna impl IntoResponse
async fn handler() -> Json<Dados> {
Json(dados)
}
2. Extractors
// Actix Web
async fn handler(
path: web::Path<(u64,)>,
query: web::Query<Filtro>,
body: web::Json<Payload>,
) -> HttpResponse { ... }
// Axum
async fn handler(
Path(id): Path<u64>,
Query(filtro): Query<Filtro>,
Json(payload): Json<Payload>,
) -> impl IntoResponse { ... }
3. Estado
// Actix Web: web::Data<T>
async fn handler(data: web::Data<AppState>) -> HttpResponse { ... }
// Axum: State<T>
async fn handler(State(state): State<AppState>) -> impl IntoResponse { ... }
4. Rotas
// Actix Web
App::new()
.route("/usuarios/{id}", web::get().to(obter_usuario))
// Axum
Router::new()
.route("/usuarios/{id}", get(obter_usuario))
A migração geralmente é tranquila, pois ambos seguem padrões similares. O maior trabalho será adaptar middleware customizado.
Conclusão
Tanto Axum quanto Actix Web são excelentes escolhas para desenvolvimento web em Rust. A tendência atual do ecossistema aponta para o Axum como a escolha padrão para novos projetos, principalmente pela integração nativa com Tokio e Tower. No entanto, Actix Web continua sendo uma opção sólida e battle-tested, especialmente se você já tem projetos funcionando nele.
A recomendação prática: para novos projetos, comece com Axum. Para projetos existentes em Actix Web, não há urgência em migrar — o framework continua ativo e performático. Para uma visão mais ampla do ecossistema web em Rust, confira nosso artigo sobre Rust para Desenvolvimento Web.