Editor’s note: This article covering the best Rust frameworks for web development was last updated by Eze Sunday on 2 September 2024 to provide updated code blocks, as well as to remove outdated frameworks that are no longer being maintained.
Rust is one of the most popular languages for developers because of its open source, fast, reliable, and high-performance features. When building a new API in Rust, it is important to consider the benefits and drawbacks of web frameworks for both frontend and backend development.
In this article, we will discuss what a web framework is and explore the various web frameworks in the Rust ecosystem for frontend and backend development in no particular order.
Let’s get started.
A web framework is a software tool that supports the development of web applications; a web framework can range from a small codebase for micro apps to a large codebase for enterprise apps and everything in between.
The most extensive web frameworks provide libraries of support for databases, templating, sessions, migration, and other utilities to speed up the development process. More simplistic frameworks focus more on one area, either the backend or frontend, and sometimes without a lot of features.
Whatever your project needs, web frameworks can provide the web services, web resources, and web APIs that development teams need to help bring their ideas to life. When choosing the appropriate web framework for your project, your development team should consider the relative importance of the following:
Rust’s memory safety guarantees security, which is achieved via its ownership model. However, not all Rust web frameworks handle security features, like cross-site scripting (XSS) and cross-site request forgery (CSRF), equally. So, you should look out for how security is handled in the framework.
Framework flexibility often comes down to how much control you need versus how much you want to rely on abstractions and conventions. Depending on your experience, you might want to consider the flexibility of the framework and how it benefits your project.
Smaller projects may benefit from using simpler, higher-level abstractions, while larger projects require scalability and efficient concurrency.
Keeping up-to-date with a framework’s development is important — you don’t want to start using a framework whose last update was five years ago, as it may impact both security and compatibility with the latest Rust features.
Clear, well-structured documentation can significantly speed up development, especially when onboarding new developers.
Community size and engagement can determine how easy it is to find resources, libraries, and help when issues arise in your project journey — “bugs are part of the job” 🙂.
Depending on your project’s priorities, different web frameworks will help you address your most pressing development requirements. In this article, we will specifically discuss frameworks built with Rust.
Web frameworks make web development and building desktop applications easier for developers. By standardizing the building process and automating common activities and tasks, web frameworks can save developers time and even promote reusing code to increase efficiency.
In the following sections, we will review web frameworks in Rust as they pertain to both frontend and backend development.
WebAssembly (Wasm) is a type of coding in low-level languages that can be run in modern web browsers. It supports C/C++, C#, Go, and Rust, with a target compilation for byte code so it can be run on the web with nearly-native performance. Wasm output is run alongside JavaScript and can be published to npm and other packages.
Rust uses a tool called wasm-pack
to assemble and package crates that target Wasm. To learn more about Wasm and Rust, check out our guide to getting started with WebAssembly and Rust.
Yew is one of the most popular Rust frameworks (it currently has 30.5k stars on GitHub) for building modern web applications. Inspired by React, it leverages a component-based architecture and provides support for state management, async, and more.
Here is a simple example of a Hello World
app with Yew:
You can quickly explore how it works by running the following commands (ensure you have Rust installed):
cargo install generate cargo install trunk cargo generate --git https://github.com/yewstack/yew-trunk-minimal-template trunk serve --open
The above snippet of code will generate a boilerplate code that you can use as a starting template for your Yew app. The reason we installed Trunk is because Yew uses a Trunk bundler to serve HTML for the web.
Perseus is a Rust framework for building reactive web applications. It supports functionalities similar to Next.js but is designed for the Rust ecosystem.
Perseus’ reactive system is powered by the Sycamore reactive library and has native support for server-side rendering (SSR) and static site generation (SSG). It currently has over 2.8k GitHub stars.
Here is an example of how you can write a simple Hello World
application with Perseus:
use perseus::prelude::*; use sycamore::prelude::*; #[perseus::main(perseus_axum::dflt_server)] pub fn main<G: Html>() -> PerseusApp<G> { PerseusApp::new() .template( Template::build("index") .view(|cx| { view! { cx, p { "Hello World!" } } }) .build() ) }
To get started with Perseus, run the command below to create a sample app and start the server:
cargo install perseus-cli perseus new my-app cd my-app/ perseus serve -w
Sauron is a micro frontend framework that was inspired by Elm Architecture. It supports events, state management, and client-side, and server-side web development. One of the easiest ways to experiment with how it works is by using the html2sauron to convert HTML into Sauron source code like so:
Sauron has above 2k GitHub stars, which is really impressive for a new framework. It shows that the interest in the framework is growing.
Dioxus is a Rust UI library that lets you build reactive cross-platform UI components — it supports web, mobile, and desktop app development. It borrows some of its features from React (including hooks) and uses its own virtual DOM— you can think of it as a hybrid of React with the safety and speed of Rust.
This is how a component looks like in a Dioxus app:
fn app(cx: Scope) -> Element { let result: &mut u32 = cx.use_hook(|| 0); cx.render(rsx!( div { "Hello World" } )) }
Dioxus has one of the largest community support with over 20k GitHub stars.
Iced is a GUI library for cross-platform development with batteries included. Its architecture is also inspired by the Elm Architecture and offers built-in support for reactive programming, type safety, and speed.
Iced is a little bit opinionated; it expects you to write your code using the following structure:
This is a great way to split user interfaces into different concepts that are easy to reason about and find exactly what you are looking for in the codebase.
The community for Iced is growing rapidly as well, with over 24k stars on GitHub.
Tauri is a Rust-based library that enables you to build lightweight desktop applications by leveraging web technologies like HTML, CSS, and JavaScript for the UI. You can use any frontend framework of your choice that compiles to HTML, CSS, and JavaScript.
Unlike Electron (a JavaScript desktop app development framework), which relies on Chromium and Node.js, Tauri uses the system’s native web view. This makes it possible to have even smaller binary sizes and more efficient resource usage.
You can use the Tauri framework to develop a full-stack desktop app from the frontend to the backend logic.
Tauri probably has the largest community support with over 81k GitHub stars as of the time of this writing.
Backend development is the aspect of web development that is focused on server-side operations. A typical backend framework includes features like database management, session handling, templating, ORM, and database migrations for building and maintaining reliable web apps.
Various web frameworks in the Rust ecosystem enable backend development, which we’ll discuss in this section.
Rocket is a popular Rust async web framework that simplifies development. It abstracts many of the underlying complexities of web development so you can focus on building your main business logic with a user-friendly API without compromising security and speed.
As one of the earliest Rust frameworks, it has a large active developer community with over 24k stars on GitHub at the time of this writing.
Here is a simple example of a Rocket server that takes two query parameters and returns a Happy Birthday message:
#[macro_use] extern crate rocket; #[get("/<name>/<age>")] fn birthday(name: &str, age: u8) -> String { format!("Yayyy, {}, you are {} years old! Happy Birthday to you.", name, age) } #[launch] fn rocket() -> _ { rocket::build().mount("/birthday-message", routes![hello]) }
Actix Web is a backend web framework that is based on the actor model and allows you to build complex web applications at scale. While it’s simple, it exposes low-level implementations to enable further customization.
It has a large developer community, with over 21k GitHub stars as of the time of this writing.
Here is a simple Happy Birthday API example using Actix Web to get an overview of what it looks like:
use actix_web::{get, web, App, HttpServer, Responder}; #[get("/birthday-message/{name}/{age}")] async fn birthday(name: web::Path<(String, u8)>) -> impl Responder { format!( "Hello, {}, you are {} years old! Happy Birthday!", name.0, name.1 ) } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new().service(birthday)) .bind("127.0.0.1:8080")? .run() .await }
If you are looking to adopt Actix Web for your project, I suggest you read our Actix Web adoption guide for more insights.
Axum is a modern, async-first web framework built on top of the popular Tokio ecosystem, designed for building scalable and maintainable web applications.
Axum is a very robust web framework, while it doesn’t expose much of its low-level implementation to avoid complexity because it tries to be more friendly to new developers in the community, so you might not see a lot of scary generics compared to Actix as it abstracts some of most of them away. However, it’s highly capable and supports many modern web APIs like HTTP/2, WebSockets, etc.
One of my best features of Axum is how it makes building middleware a lot easier for beginners compared to Actix Web. We’ve written an article about JWT authentication with Axum, which might help you learn more about how Axum’s middleware system works.
Here is a simple server setup code using Axum that returns a Happy Birthday message:
use axum::{extract::Path, routing::get, Router}; async fn birthday(Path((name, age)): Path<(String, u8)>) -> String { format!( "Yayyy, {}, you are {} years old! Happy Birthday to you.", name, age ) } #[tokio::main] async fn main() { let app = Router::new().route("/birthday/:name/:age", get(birthday)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); }
Axum’s community is large and growing, as of the time of writing this article, it stands at 18.3k stars.
Warp is designed to be fast, lightweight, and composable. It’s easy to get started with it as soon as possible and start building highly performant APIs.
To further illustrate how easy it is to get started with Warp, here is a simple API mimicking the same Happy Birthday example we’ve been using. It looks much shorter now and still easy to understand:
use warp::Filter; #[tokio::main] async fn main() { let birthday = warp::path!("birthday" / String / u8) .map(|name, age| { format!("Yayyy, {}, you are {} years old! Happy Birthday to you.", name, age) }); warp::serve(birthday) .run(([127, 0, 0, 1], 3030)) .await; }
As of the time of this writing, Warp has over 9.5k stars on GitHub and its developer community continues to grow!
Gotham is a flexible web framework built for stable Rust that promotes “stability, safety, security, and speed.” It provides async support with the help of Tokio and hyper out of the box.
Gotham supports routing, extractors (type-safe data requests), middleware, state sharing, and testing. Unfortunately, it does not have structure, boilerplate, database support, or anything else you need to build a full-fleshed web application.
Here is a simple Happy Birthday app with Gotham:
extern crate gotham; use gotham::helpers::http::response::create_response; use gotham::hyper::{Body, Response, StatusCode}; use gotham::state::State; fn birthday(state: State) -> (State, Response<Body>) { let res = format!("Happy Birthday! 🎉"); let body = create_response(&state, StatusCode::OK, gotham::mime::TEXT_PLAIN, res); (state, body) } fn main() { gotham::start("127.0.0.1:7878", || Ok(birthday)); }
Rouille is a microweb framework that employs a linear request and response design via a listening socket that parses HTTP requests.
It is built for simple applications and it doesn’t come with batteries included, however, it is agnostic enough to allow you to use any library you wish to integrate into your project. For example, because it doesn’t have native middleware support, you can easily integrate the Hyper Middleware library to handle your middleware system.
Rouille is still very young and currently has about 1.1k GitHub stars. Here is a simple Hello World application built with Rouille:
use rouille::Request; use rouille::Response; rouille::start_server("0.0.0.0:80", move |request| { Response::text("hello world") });
Thruster is a fast, middleware-based Rust web framework inspired by the layering and design of Koa and Express.js. It is SSL-ready, secure, intuitive, and testable.
Thruster is built to accommodate async/await and provides support for middleware, error handling, databases, and testing.
Thruster is as young as the Rouille framework and the community is not very big yet.
Here is a quick Happy Birthday code overview of how Thruster works:
use thruster::{m, middleware_fn, App, BasicContext as Ctx, MiddlewareNext, Request, Server}; use thruster::{MiddlewareResult, ThrusterServer}; #[middleware_fn] async fn birthday(mut context: Ctx, _next: MiddlewareNext<Ctx>) -> MiddlewareResult<Ctx> { let mut context = Ctx::default(); context.body("Happy Birthday! 🎉"); Ok(context) } #[tokio::main] async fn main() { let mut app = App::<Request, Ctx, ()>::new_basic() .get("/hello", m!(birthday)); let server = Server::new(app); server.build("0.0.0.0", 4321).await; }
Tide is a minimal framework similar to Express.js (Node.js), Sinatra (Ruby), and Flask (Python) for rapid development that promotes asynchronously building web apps. It has most of the functionalities you’ll find in most mature web frameworks including, routing, auth, socket, log, template engines, middleware, testing, and other utilities.
Tide uses async-std
, which is built for speed and safety for its asynchronous implementation. Tide has a huge growing community compared to Thruster and Rouille — it has about 5k stars on GitHub as well.
Here is a simple Happy Birthday application with Tide:
use tide::Request; async fn birthday(_req: Request<()>) -> tide::Result<String> { Ok("Happy Birthday! 🎉".into()) } #[async_std::main] async fn main() -> tide::Result<()> { let mut app = tide::new(); app.at("/birthday").get(birthday); app.listen("127.0.0.1:8080").await?; Ok(()) }
Dropshot is a simple and lightweight server-side library for creating REST APIs. It has support for OpenAPI specs, async, and logging. You’ll like it if you just want to expose a few APIs in your project. It’s not a full web framework (at least, I won’t consider it to be one) for all web development use cases.
Dropshot has less than 1,000 GitHub stars as of the time of this writing.
Actix, Rocket, Axum, and Warp are all popular web frameworks for Rust, each with its own unique features and strengths. Here’s a closer look at the commonalities found for each of them:
Features | Explanation | Actix Web | Rocket | Axum | warp |
---|---|---|---|---|---|
Async/await support | Actix, Rocket, Axum, and warp all use Rust’s async/await syntax to provide non-blocking I/O operations for web applications. This allows for better performance and scalability, as the framework can handle multiple requests simultaneously without blocking or slowing down. | ✅ | ✅ | ✅ | ✅ |
Middleware | Middleware is a common feature in web frameworks that allows developers to add functionality to the request-response cycle, such as logging, authentication, and error handling. All of the most popular Rust web frameworks – Actix, Rocket, Tide, and warp – support middleware. | ✅ | ✅ | ✅ | ✅ |
WebSockets support | They all support WebSocket but the specific syntax and features for working with WebSockets may vary across the frameworks, so the choice of framework will depend on the specific needs of the project. | ✅ | ✅ | ✅ | ✅ |
Concurrency & Performance | Actix and Axum may be better suited for applications that require high levels of concurrency and performance, while Rocket and warp may be better suited for applications that prioritize ease of use and flexibility. | ✅ | 🚫 | ✅ | 🚫 |
Cookie and session | Cookies and sessions are important components of many web applications, allowing developers to store and retrieve data that is associated with a specific user or client | ✅ | ✅ | ✅ | ✅ |
GitHub stars | All four web frameworks have active communities and are continuing to grow in popularity. | 21K | 24k | 18.3k | 9.5k |
In this article, we discussed the different Rust web frameworks. This list is by no means exhaustive. However, it covers the most popular web frameworks. While the choice of which framework to use will largely depend on your project requirement, this list should give you a head start to further your research.
Good luck!
Debugging Rust applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking the performance of your Rust apps, automatically surfacing errors, and tracking slow network requests and load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Rust application. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Modernize how you debug your Rust apps — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
14 Replies to "Exploring the top Rust web frameworks"
Let’s not forget dropshot by oxide computer company.
No Warp?
Yeah, you’re missing Warp, it’s the Tokio equivalent to Tide. Warp and Tide are both quite good, it just depends on whether you favor async-std or tokio.
Also, I think Iced deserves a mention here, since it can compile to WebAssembly and WebGPU, in addition to platform-native Metal, Vulkan, and OpenGL. Also, people are even experimenting pairing Iced with cargo-mobile, which is also exciting!
+1 to this
warp and (warp-based) rweb definitely are missing from the overview
How can you say Rocket is production-ready when it can’t even compile with stable Rust? In my environment, I will have to wait until there’s a release that can run on stable Rust. Hopefully it’s coming soon with Rocket v0.5.
> Rocket is a popular, mature web framework
Latest Release: 0.5.0
As long as it hasn’t reached 1.0, you can’t really call it mature, now can you? It’s an admission from the developers themselves that they have not implemented everything on the roadmap yet.
Sauron isn’t outdated. It is still being actively developed. Seed is effectively dead, and Yew’s syntax and performance are vastly inferior to it. By far the best frontend web framework at the moment.
Why do you say that? By Github stats, both Sauron and Seed went on life support six months ago, like Stdweb and Percy did a year ago. Only Yew is maintaining its velocity and only Smithy looks dead.
Axum is missing 🙂
friendly explained
Hi, it appears you’ve updated the article, and yet you list warp and axum as being not “production-ready”. You never explain your criteria for this subjective determination, but you also list warp as not supporting either concurrency or async-await, and axum as not supporting async-await, and yet, I’m literally doing that here:
https://github.com/diba-io/carbonado-node/blob/cb134b57c260d48a405fbd2199c3201468e1259e/src/frontend/http.rs
So, these specific claims are objectively false.
As for the “production-readiness” of frontend frameworks, Iced is used by System76 for their new desktop software on Pop!_OS, which is a very popular operating system that they ship on millions of dollars worth of hardware. See:
https://www.phoronix.com/news/COSMIC-Desktop-Iced-Toolkit
Dioxus and Tauri are also making leaps and bounds of progress, and there’s a big effort towards the modernization of Yew as well. If anyone wants my recommendation, well, it depends on the use-case, but I’d recommend looking into Dioxus, Axum, and Tauri. Iced is also a very capable UI library, but I don’t think it’s as good in web contexts anymore. Rust is actually a very flexible language, and WebAssembly support has come a long way.
Really, this article just isn’t going to age well. You should probably remove it, or add a big huge giant disclaimer, “These are just my opinions and I don’t actually know very much about what I’m writing about at all lololol”. Otherwise you’re just providing disinformation on what’s likely a prominent search engine query, and will continue to do so as the ecosystem matures.
I appreciate the feedback and I can understand why you may feel that way.
Regarding the production readiness of certain Rust frameworks, I must clarify that it is not my intention to discredit any framework or library in the Rust ecosystem.
However, it is important to note that the criteria for production readiness can be subjective and depend on a variety of factors, such as community support, stability, performance, and security. In the article, I may have overlooked certain factors or not provided enough context for why I came to the conclusion that a particular framework may not be production ready.
I would update the article by buttressing more on the criteria to which the frameworks are ready for production and as well add some of the companies that use each one of them.
Once again, I appreciate your feedback and will use it to improve the quality of my content going forward.
I do agree with the poster that I was confused by the parts regarding Axum not having async support when Axum is an async framework built on top of Tokio, the rust async runtime, as mentioned in the article.