A powerful, pragmatic, and extremely fast web framework for Rust

Get Started

Type Safe

Forget about stringly typed objects, from request to response, everything has types.

Feature Rich

Out of the box logging, body compression, static file serving, TLS, HTTP/2, and much more.

Extensible

Easily create and share reusable components for any Actix Web application.

Blazingly Fast

Actix Web is blazingly fast. Don't take our word for it -- see for yourself!

use actix_web::{get, web, App, HttpServer, Responder};

#[get("/hello/{name}")]
async fn greet(name: web::Path<String>) -> impl Responder {
    format!("Hello {name}!")
}

#[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/hello", web::get().to(|| async { "Hello World!" }))
            .service(greet)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

Flexible Responders

Handler functions in Actix Web can return a wide range of objects that implement the Responder trait. This makes it a breeze to return consistent responses from your APIs.

async fn current_temperature() -> impl Responder {
    web::Json(json!({ "temperature": 42.3 }))
}

async fn hello_world() -> actix_web::Result<impl Responder> {
  Ok("Hello World!")
}

Powerful Extractors

Actix Web comes with a powerful extractor system that extracts parts of the incoming HTTP request and passes it to your handler functions.

A handler function can receive up to 12 arguments that implement the FromRequest trait, in any order, and Actix Web will automatically extract them from the request and provide them. It feels like magic!

#[derive(Deserialize, Serialize)]
struct EventForm {
    kind: String,
    tags: Vec<String>,
}

async fn capture_event(evt: web::Json<EventForm>, db: web::Data<Db>) -> impl Responder {
    let new_event = db.store(&evt.kind, &evt.tags).await;
    format!("got event {}", new_event.id.unwrap())
}

Easy Form Handling

Handling multipart/urlencoded form data is easy. Just define a structure that can be deserialized and Actix Web will handle the rest.

use actix_web::web::{Either, Json, Form};

#[derive(Deserialize)]
struct Register {
    username: String,
    country: String,
}

// register form is JSON
async fn register(form: web::Json<Register>) -> impl Responder {
    format!("Hello {} from {}!", form.username, form.country)
}

// register form can be either JSON or URL-encoded
async fn register(form: Either<Json<Register>, Form<Register>>) -> impl Responder {
  let Register { username, country } = form.into_inner();
  format!("Hello {username} from {country}!")
}

Request Routing

The built-in Actix Web request router can be used with or without macros attached to handlers, and always provides flexible and composable methods of creating routing tables.

Includes support for matching dynamic path segments, path prefix groups, and custom routing guards which let you define your own rules.

#[get("/")]
async fn index(_req: HttpRequest) -> impl Responder {
    "Hello from the index page!"
}

async fn hello(path: web::Path<String>) -> impl Responder {
    format!("Hello {}!", &path)
}

let app = App::new()
    .service(index)
    .route("/{name}", web::get().to(hello));