#web-framework #async #web-server #framework

salvo_core

Salvo is a powerful web framework that can make your work easier

220 releases (87 breaking)

Uses new Rust 2024

new 0.92.0 Apr 17, 2026
0.90.1 Apr 2, 2026
0.89.3 Mar 18, 2026
0.87.1 Dec 31, 2025
0.1.6 Feb 23, 2020

#2994 in HTTP server

Download history 34697/week @ 2025-12-26 45974/week @ 2026-01-02 30701/week @ 2026-01-09 41153/week @ 2026-01-16 56451/week @ 2026-01-23 39791/week @ 2026-01-30 43875/week @ 2026-02-06 44870/week @ 2026-02-13 40278/week @ 2026-02-20 20810/week @ 2026-02-27 30083/week @ 2026-03-06 13698/week @ 2026-03-13 23562/week @ 2026-03-20 22320/week @ 2026-03-27 16953/week @ 2026-04-03 22547/week @ 2026-04-10

87,233 downloads per month
Used in 132 crates (24 directly)

Apache-2.0

760KB
17K SLoC

Salvo

A powerful and simple Rust web framework

English   简体中文   繁體中文

build status build status build status codecov
crates.io Documentation Download unsafe forbidden Rust Version
Website

Features

  • Simple & Powerful - Minimal boilerplate. If you can write a function, you can write a handler.
  • HTTP/1, HTTP/2 & HTTP/3 - Full protocol support out of the box.
  • Flexible Routing - Tree-based routing with middleware support at any level.
  • Auto TLS - ACME integration for automatic certificate management.
  • OpenAPI - First-class OpenAPI support with auto-generated documentation.
  • WebSocket & WebTransport - Real-time communication built-in.
  • Built on Hyper & Tokio - Production-ready async foundation.

Quick Start

Create a new project:

cargo new hello-salvo
cd hello-salvo
cargo add salvo tokio --features salvo/oapi,tokio/macros

Write your first app in src/main.rs:

use salvo::prelude::*;

#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

#[tokio::main]
async fn main() {
    let router = Router::new().get(hello);
    let acceptor = TcpListener::new("127.0.0.1:7878").bind().await;
    Server::new(acceptor).serve(router).await;
}

Run it:

cargo run

Why Salvo?

Middleware = Handler

No complex traits or generics. Middleware is just a handler:

#[handler]
async fn add_header(res: &mut Response) {
    res.headers_mut().insert(header::SERVER, HeaderValue::from_static("Salvo"));
}

Router::new().hoop(add_header).get(hello)

Tree Routing with Middleware

Apply middleware to specific route branches:

Router::new()
    // Public routes
    .push(Router::with_path("articles").get(list_articles))
    // Protected routes
    .push(Router::with_path("articles").hoop(auth_check).post(create_article).delete(delete_article))

OpenAPI in One Line

Just change #[handler] to #[endpoint]:

#[endpoint]
async fn hello() -> &'static str {
    "Hello World"
}

Auto HTTPS with ACME

Get TLS certificates automatically from Let's Encrypt:

let listener = TcpListener::new("0.0.0.0:443")
    .acme()
    .add_domain("example.com")
    .http01_challenge(&mut router)
    .quinn("0.0.0.0:443"); // HTTP/3 support

CLI Tool

cargo install salvo-cli
salvo new my_project

Learn More

  • Savhub - Easily manage your AI skills. A platform built with Salvo for organizing and sharing AI capabilities.
  • Palpo - A Matrix server implementation in Rust, powered by Salvo.

Check out the full list of community projects in our ECOSYSTEM.md.

Performance

Salvo consistently ranks among the fastest Rust web frameworks:

Support

If you find Salvo useful, consider buying me a coffee.

License

Licensed under Apache License 2.0.

Dependencies

~23–57MB
~1M SLoC