Para desenvolvimento web em Rust, a escolha padrão em 2026 é Axum: framework mantido pela equipe do Tokio, com extractors tipados e middleware do ecossistema Tower. Actix Web entrega a maior performance bruta, Rocket prioriza produtividade e Leptos permite full-stack com frontend Rust compilado para WebAssembly. Neste guia você compara os quatro, constrói uma API REST completa com Axum e vê o caminho de deploy com Docker adotado por empresas como Cloudflare, Discord, Shopify e AWS.
O ecossistema web de Rust amadureceu enormemente nos últimos anos. Em 2026, desenvolver aplicações web com Rust deixou de ser uma aposta experimental para se tornar uma escolha estratégica. A combinação de performance próxima a C, segurança de memória garantida em tempo de compilação e um ecossistema assíncrono robusto torna Rust uma opção cada vez mais atraente para backends de alta carga, APIs REST e até aplicações full-stack.
Se você vem de Node.js, Go ou Python, vai perceber que Rust exige mais rigor no código, mas recompensa com servidores que consomem frações da memória e respondem com latências consistentemente baixas, sem pausas de garbage collector.
Qual framework escolher? Tabela comparativa
| Framework | Melhor para | Estilo | Full-stack | Highlights |
|---|---|---|---|---|
| Axum | APIs REST e microserviços (escolha padrão) | Handlers async sem macros + Tower | Não | Extractors tipados, Tokio nativo, maior comunidade |
| Actix Web | Latência mínima, alta concorrência | Modelo de atores | Não | Topo dos benchmarks TechEmpower |
| Rocket | Produtividade, projetos menores | Macros procedurais | Não | Convenção sobre configuração |
| Leptos | Full-stack Rust com SSR | Componentes reativos | Sim | Frontend WASM + backend Rust nativo |
Principais Frameworks e Bibliotecas
Axum — O Framework Favorito da Comunidade
Axum é mantido pela equipe do Tokio e se tornou o framework web mais popular do ecossistema Rust. Ele se destaca pela ergonomia dos extractors, integração nativa com o Tower middleware ecosystem e tipagem forte para rotas.
Actix Web — Performance Bruta
Actix Web consistentemente lidera os benchmarks do TechEmpower. Usa um modelo de atores e é ideal quando cada milissegundo de latência importa.
Rocket — Simplicidade e Produtividade
Rocket prioriza a experiência do desenvolvedor com macros procedurais que reduzem boilerplate. Ideal para projetos menores ou equipes que valorizam convenção sobre configuração.
Leptos — Full-Stack Rust com SSR
Leptos permite escrever frontend e backend em Rust, com Server-Side Rendering (SSR), hidratação e componentes reativos — tudo compilando para WebAssembly no cliente e Rust nativo no servidor. Compare com Dioxus e Yew no guia de frameworks full-stack.
Configuração Base (Cargo.toml)
[package]
name = "minha-api-web"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.8"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tower = "0.5"
tower-http = { version = "0.6", features = ["cors", "trace", "compression-gzip"] }
tracing = "0.1"
tracing-subscriber = "0.3"
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"] }
Exemplo Prático: API REST Completa com Axum
Vamos construir uma API de gerenciamento de tarefas com rotas CRUD, middleware de logging e tratamento de erros estruturado.
use axum::{
extract::{Path, State},
http::StatusCode,
routing::{get, post, put, delete},
Json, Router,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;
use tower_http::trace::TraceLayer;
use tower_http::cors::CorsLayer;
// Modelos
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Tarefa {
id: u64,
titulo: String,
descricao: String,
concluida: bool,
}
#[derive(Debug, Deserialize)]
struct NovaTarefa {
titulo: String,
descricao: String,
}
#[derive(Debug, Deserialize)]
struct AtualizarTarefa {
titulo: Option<String>,
descricao: Option<String>,
concluida: Option<bool>,
}
// Estado compartilhado
type AppState = Arc<RwLock<Vec<Tarefa>>>;
// Handlers
async fn listar_tarefas(State(state): State<AppState>) -> Json<Vec<Tarefa>> {
let tarefas = state.read().await;
Json(tarefas.clone())
}
async fn criar_tarefa(
State(state): State<AppState>,
Json(nova): Json<NovaTarefa>,
) -> (StatusCode, Json<Tarefa>) {
let mut tarefas = state.write().await;
let tarefa = Tarefa {
id: tarefas.len() as u64 + 1,
titulo: nova.titulo,
descricao: nova.descricao,
concluida: false,
};
tarefas.push(tarefa.clone());
(StatusCode::CREATED, Json(tarefa))
}
async fn obter_tarefa(
State(state): State<AppState>,
Path(id): Path<u64>,
) -> Result<Json<Tarefa>, StatusCode> {
let tarefas = state.read().await;
tarefas
.iter()
.find(|t| t.id == id)
.cloned()
.map(Json)
.ok_or(StatusCode::NOT_FOUND)
}
async fn atualizar_tarefa(
State(state): State<AppState>,
Path(id): Path<u64>,
Json(dados): Json<AtualizarTarefa>,
) -> Result<Json<Tarefa>, StatusCode> {
let mut tarefas = state.write().await;
let tarefa = tarefas
.iter_mut()
.find(|t| t.id == id)
.ok_or(StatusCode::NOT_FOUND)?;
if let Some(titulo) = dados.titulo {
tarefa.titulo = titulo;
}
if let Some(descricao) = dados.descricao {
tarefa.descricao = descricao;
}
if let Some(concluida) = dados.concluida {
tarefa.concluida = concluida;
}
Ok(Json(tarefa.clone()))
}
async fn deletar_tarefa(
State(state): State<AppState>,
Path(id): Path<u64>,
) -> StatusCode {
let mut tarefas = state.write().await;
let len_antes = tarefas.len();
tarefas.retain(|t| t.id != id);
if tarefas.len() < len_antes {
StatusCode::NO_CONTENT
} else {
StatusCode::NOT_FOUND
}
}
#[tokio::main]
async fn main() {
// Inicializar tracing
tracing_subscriber::fmt::init();
let state: AppState = Arc::new(RwLock::new(Vec::new()));
let app = Router::new()
.route("/tarefas", get(listar_tarefas).post(criar_tarefa))
.route(
"/tarefas/{id}",
get(obter_tarefa)
.put(atualizar_tarefa)
.delete(deletar_tarefa),
)
.layer(TraceLayer::new_for_http())
.layer(CorsLayer::permissive())
.with_state(state);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
tracing::info!("Servidor rodando em http://localhost:3000");
axum::serve(listener, app).await.unwrap();
}
Tower Middleware — O Poder Composicional
Uma das maiores vantagens do ecossistema Axum/Tower é a possibilidade de compor middleware de forma tipada:
use axum::Router;
use tower::ServiceBuilder;
use tower_http::{
compression::CompressionLayer,
cors::CorsLayer,
limit::RequestBodyLimitLayer,
trace::TraceLayer,
};
use std::time::Duration;
fn configurar_middleware(app: Router) -> Router {
app.layer(
ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new())
.layer(CorsLayer::permissive())
.layer(RequestBodyLimitLayer::new(1024 * 1024)) // 1MB
)
}
Leptos: Full-Stack Rust
Para quem deseja escrever frontend e backend em Rust, Leptos oferece uma experiência semelhante ao React/SolidJS:
use leptos::prelude::*;
#[component]
fn ContadorTarefas() -> impl IntoView {
let (contagem, set_contagem) = signal(0);
view! {
<div class="contador">
<h2>"Tarefas concluídas: " {contagem}</h2>
<button on:click=move |_| set_contagem.update(|n| *n += 1)>
"Concluir tarefa"
</button>
</div>
}
}
Deploy em Produção
Dockerfile Multi-Stage
FROM rust:1.85 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/minha-api-web /usr/local/bin/
EXPOSE 3000
CMD ["minha-api-web"]
O binário final terá entre 5-15MB e consumirá apenas 2-5MB de RAM em idle, uma fração do que um servidor Node.js ou Python equivalente usaria.
Empresas Usando Rust na Web
- Cloudflare: Proxy reverso, Workers runtime e ferramentas de rede — grande parte da infraestrutura de borda é Rust
- Discord: Migrou serviços críticos de Go para Rust, reduzindo latência e consumo de memória drasticamente
- Shopify: Usa Rust para componentes de alta performance no checkout e processamento de pagamentos
- AWS: Serviços internos e bibliotecas como o SDK da AWS para Rust
- Figma: Servidor multiplayer de colaboração em tempo real reescrito em Rust
- 1Password: Backend de sincronização e criptografia
Como Começar
Se você quer desenvolver aplicações web com Rust, recomendamos o seguinte caminho de aprendizado:
- Fundamentos: Domine ownership, borrowing e lifetimes com nosso tutorial de primeiros passos
- Async Rust: Entenda futures e o runtime Tokio com a receita de async/await básico
- Serialização: Aprenda serde com as receitas de JSON e serialização
- Primeira API: Siga o tutorial completo de API REST com Axum
- Banco de dados: Conecte ao PostgreSQL com nosso tutorial de Rust + PostgreSQL e a referência de SQLx
- Deploy: Configure Docker e GitHub Actions para CI/CD
Conclusão
O desenvolvimento web com Rust em 2026 é uma realidade madura e produtiva. Frameworks como Axum oferecem ergonomia comparável ao Express.js ou Flask, enquanto entregam performance que compete com C++. Se seu projeto precisa de alta performance, baixo consumo de recursos ou latência previsível, Rust é uma escolha excelente para o backend — e com Leptos, até para o frontend.
Veja Também
- Tutorial: API REST com Axum — Construa uma API completa passo a passo
- Receita: Criar Servidor HTTP — Servidor HTTP básico em poucas linhas
- Rust para APIs GraphQL — Alternativa ao REST com async-graphql
- Rust para Microsserviços — Arquitetura de microsserviços com Tonic e gRPC
- Rust para WebAssembly — Leve Rust para o navegador
- Rust para DevOps — Otimize containers e pipelines CI/CD
- Vagas Rust no Brasil — Encontre oportunidades de trabalho com Rust