Top Related Projects
Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
Ergonomic and modular web framework built with Tokio, Tower, and Hyper
A super-easy, composable, web server framework for warp speeds.
A web framework for Rust.
A flexible web framework that promotes stability, safety, security and speed.
An Extensible, Concurrent Web Framework for Rust
Quick Overview
Tide is a minimal and pragmatic Rust web application framework built for rapid development. It aims to provide a simple and intuitive API for building asynchronous web applications, leveraging the power of Rust's async/await syntax and ecosystem.
Pros
- Lightweight and fast, with minimal overhead
- Easy to use and learn, especially for developers familiar with Express.js
- Built-in support for async/await, making asynchronous programming more straightforward
- Extensible middleware system for adding custom functionality
Cons
- Relatively young project compared to some other Rust web frameworks
- Smaller ecosystem and fewer third-party extensions compared to more established frameworks
- Documentation can be sparse in some areas
- May lack some advanced features found in more comprehensive frameworks
Code Examples
- Basic "Hello, World!" server:
use tide::Request;
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/").get(|_| async { Ok("Hello, World!") });
app.listen("127.0.0.1:8080").await?;
Ok(())
}
- Handling JSON requests and responses:
use tide::{Request, Response};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct User {
name: String,
age: u32,
}
async fn create_user(mut req: Request<()>) -> tide::Result {
let user: User = req.body_json().await?;
Ok(Response::builder(201)
.body(tide::Body::from_json(&user)?)
.build())
}
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/users").post(create_user);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
- Using middleware:
use tide::{Request, Next};
async fn logger<'a>(req: Request<()>, next: Next<'a, ()>) -> tide::Result {
println!("Incoming request: {} {}", req.method(), req.url());
let response = next.run(req).await;
println!("Outgoing response: {}", response.status());
Ok(response)
}
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.with(logger);
app.at("/").get(|_| async { Ok("Hello, World!") });
app.listen("127.0.0.1:8080").await?;
Ok(())
}
Getting Started
To get started with Tide, follow these steps:
-
Add Tide to your
Cargo.toml
:[dependencies] tide = "0.16.0" async-std = { version = "1.10.0", features = ["attributes"] }
-
Create a basic server in your
main.rs
:use tide::Request; #[async_std::main] async fn main() -> tide::Result<()> { let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, Tide!") }); app.listen("127.0.0.1:8080").await?; Ok(()) }
-
Run your server with
cargo run
and visithttp://localhost:8080
in your browser.
Competitor Comparisons
Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
Pros of actix-web
- Higher performance and scalability due to its actor-based architecture
- More mature and feature-rich ecosystem with extensive middleware support
- Better documentation and larger community for support
Cons of actix-web
- Steeper learning curve, especially for developers new to Rust
- More complex setup and configuration compared to Tide's simplicity
- Heavier runtime overhead for smaller applications
Code Comparison
actix-web example:
use actix_web::{web, App, HttpServer, Responder};
async fn hello() -> impl Responder {
"Hello, World!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().route("/", web::get().to(hello))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Tide example:
use tide::prelude::*;
async fn hello(_: tide::Request<()>) -> tide::Result {
Ok("Hello, World!".into())
}
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/").get(hello);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
Both frameworks offer similar functionality, but actix-web's syntax is more verbose due to its actor system, while Tide provides a more straightforward approach for simple applications.
Ergonomic and modular web framework built with Tokio, Tower, and Hyper
Pros of axum
- Built on top of Tokio, providing excellent performance and scalability
- Modular design with a rich ecosystem of extensions and middleware
- Strong typing and compile-time checks for improved safety and reliability
Cons of axum
- Steeper learning curve, especially for developers new to async Rust
- More complex setup and configuration compared to Tide's simplicity
- Heavier dependency footprint due to Tokio ecosystem
Code Comparison
Tide example:
async fn hello(req: Request<()>) -> Result {
Ok("Hello, World!".into())
}
#[async_std::main]
async fn main() -> Result<()> {
let mut app = tide::new();
app.at("/").get(hello);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
axum example:
async fn hello() -> &'static str {
"Hello, World!"
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(hello));
axum::Server::bind(&"127.0.0.1:8080".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
Both frameworks offer similar functionality, but axum leverages Tokio's async runtime and provides more advanced features at the cost of increased complexity. Tide focuses on simplicity and ease of use, making it a good choice for smaller projects or developers new to Rust web development.
A super-easy, composable, web server framework for warp speeds.
Pros of Warp
- Higher performance due to its zero-copy design and efficient routing system
- More mature and battle-tested in production environments
- Extensive middleware ecosystem and built-in features like WebSocket support
Cons of Warp
- Steeper learning curve due to its heavy use of Rust's type system
- Less straightforward for simple use cases compared to Tide's more intuitive API
- Requires more boilerplate code for basic setups
Code Comparison
Tide example:
let mut app = tide::new();
app.at("/").get(|_| async { Ok("Hello, World!") });
app.listen("127.0.0.1:8080").await?;
Warp example:
let hello = warp::path::end().map(|| "Hello, World!");
warp::serve(hello).run(([127, 0, 0, 1], 8080)).await;
Both Tide and Warp are popular Rust web frameworks, but they cater to different needs. Tide focuses on simplicity and ease of use, making it ideal for rapid prototyping and smaller projects. It has a more straightforward API and is easier to get started with for Rust beginners.
Warp, on the other hand, prioritizes performance and type safety. It leverages Rust's type system to provide compile-time guarantees and offers excellent performance for high-load applications. However, this comes at the cost of a steeper learning curve and more verbose code for simple use cases.
Choose Tide for quick development and simpler projects, or opt for Warp when performance and type safety are critical for your application.
A web framework for Rust.
Pros of Rocket
- More mature and feature-rich framework with extensive documentation
- Built-in support for templating, form handling, and database integration
- Strong compile-time guarantees and type-safe routing
Cons of Rocket
- Requires nightly Rust compiler, which may be less stable
- Steeper learning curve due to more complex architecture
- Heavier dependency footprint compared to Tide
Code Comparison
Rocket example:
#[macro_use] extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index])
}
Tide example:
use tide::prelude::*;
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/").get(|_| async { Ok("Hello, world!") });
app.listen("127.0.0.1:8080").await?;
Ok(())
}
Both Rocket and Tide are web frameworks for Rust, but they differ in complexity and features. Rocket offers a more comprehensive set of tools and stronger compile-time guarantees, while Tide focuses on simplicity and flexibility. The choice between them depends on project requirements and developer preferences.
A flexible web framework that promotes stability, safety, security and speed.
Pros of Gotham
- More mature and stable, with a longer development history
- Offers built-in middleware for common tasks like session management and authentication
- Provides a robust routing system with type-safe route parameters
Cons of Gotham
- Steeper learning curve due to more complex architecture
- Less active community and slower development pace
- Heavier and more opinionated framework compared to Tide's minimalist approach
Code Comparison
Gotham route handler:
fn say_hello(state: State) -> (State, Response) {
let response = create_response(&state, StatusCode::OK, Some("Hello, World!"));
(state, response)
}
Tide route handler:
async fn say_hello(_req: Request<()>) -> Result {
Ok("Hello, World!".into())
}
Both Gotham and Tide are web frameworks for Rust, but they have different philosophies and approaches. Gotham focuses on providing a full-featured, batteries-included experience with a strong emphasis on type safety and compile-time guarantees. Tide, on the other hand, aims for simplicity and ease of use, with a more minimalist design that allows developers to add functionality as needed.
Gotham's routing system is more powerful and flexible, but it comes at the cost of increased complexity. Tide's routing is simpler and more straightforward, making it easier for beginners to get started.
In terms of performance, both frameworks are generally fast and efficient, leveraging Rust's strengths. However, Gotham's additional features and abstractions may introduce some overhead compared to Tide's leaner approach.
An Extensible, Concurrent Web Framework for Rust
Pros of Iron
- More mature and established project with a longer history
- Extensive middleware ecosystem available
- Better documentation and community resources
Cons of Iron
- Less active development and maintenance
- Older design patterns and API conventions
- Heavier and more complex architecture
Code Comparison
Iron:
fn hello_world(_: &mut Request) -> IronResult<Response> {
Ok(Response::with((status::Ok, "Hello World!")))
}
Iron::new(hello_world).http("localhost:3000").unwrap();
Tide:
async fn hello_world(_: Request<()>) -> Result<impl Into<Response>> {
Ok("Hello World!")
}
#[async_std::main]
async fn main() -> Result<()> {
let mut app = tide::new();
app.at("/").get(hello_world);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
Iron uses a more traditional synchronous approach, while Tide embraces async/await syntax and modern Rust features. Tide's API is generally more concise and easier to read, reflecting its focus on simplicity and ergonomics. Iron's code style shows its age but remains functional and familiar to developers accustomed to older web frameworks.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Tide
API Docs | Contributing | Chat
Tide is a minimal and pragmatic Rust web application framework built for rapid development. It comes with a robust set of features that make building async web applications and APIs easier and more fun.
Getting started
In order to build a web app in Rust you need an HTTP server, and an async
runtime. After running cargo init
add the following lines to your
Cargo.toml
file:
# Example, use the version numbers you need
tide = "0.17.0"
async-std = { version = "1.8.0", features = ["attributes"] }
serde = { version = "1.0", features = ["derive"] }
Examples
Create an HTTP server that receives a JSON body, validates it, and responds with a confirmation message.
use tide::Request;
use tide::prelude::*;
#[derive(Debug, Deserialize)]
struct Animal {
name: String,
legs: u16,
}
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/orders/shoes").post(order_shoes);
app.listen("127.0.0.1:8080").await?;
Ok(())
}
async fn order_shoes(mut req: Request<()>) -> tide::Result {
let Animal { name, legs } = req.body_json().await?;
Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into())
}
$ curl localhost:8080/orders/shoes -d '{ "name": "Chashu", "legs": 4 }'
Hello, Chashu! I've put in an order for 4 shoes
$ curl localhost:8080/orders/shoes -d '{ "name": "Mary Millipede", "legs": 750 }'
Hello, Mary Millipede! I've put in an order for 750 shoes
See more examples in the examples directory.
Tide's design:
- Rising Tide: building a modular web framework in the open
- Routing and extraction in Tide: a first sketch
- Middleware in Tide
- Tide's evolving middleware approach
- Tide, the present and future of
- Tide channels
Community Resources
To add a link to this list, edit the markdown
file and
submit a pull request (github login required)
Listing here
does not constitute an endorsement or recommendation from the tide
team. Use at your own risk.
Listeners
- tide-rustls TLS for tide based on async-rustls
- tide-acme HTTPS for tide with automatic certificates, via Let's Encrypt and ACME tls-alpn-01 challenges
Template engines
- tide-tera
- tide-handlebars
- askama (includes support for tide)
Routers
Auth
Testing
Middleware
- tide-compress
- tide-sqlx - SQLx pooled connections & transactions
- tide-trace
- tide-tracing
- opentelemetry-tide
- driftwood http logging middleware
- tide-compressed-sse
- tide-websockets
- tide-csrf
- tide-flash
Session Stores
- async-redis-session
- async-sqlx-session (sqlite, mysql, postgres, ...)
- async-mongodb-session
Example applications
- dot dot vote
- tide-example (sqlx + askama)
- playground-tide-mongodb
- tide-morth-example
- broker (backend as a service)
- tide-basic-crud (sqlx + tera)
- tide-graphql-mongodb
- Clean boilerplate for graphql services using tide, rhai, async-graphql, surf, graphql-client, handlebars-rust, jsonwebtoken, and mongodb.
- Graphql Services: User register, Salt and hash a password with PBKDF2 , Sign inï¼ JSON web token authentication, Change passwordï¼ Profile Update, User's query & mutation, and Project's query & mutation.
- Web Application: Client request, bring & parse GraphQL data, Render data to template engine(handlebars-rust)ï¼ Define custom helper with Rhai scripting language.
- surfer
- The Blog built on Tide stack, generated from tide-graphql-mongodb.
- Backend for graphql services using tide, async-graphql, jsonwebtoken, mongodb and so on.
- Frontend for web application using tide, rhai, surf, graphql_client, handlebars-rust, cookie and so on.
- tide-server-example
Contributing
Want to join us? Check out our The "Contributing" section of the guide and take a look at some of these issues:
Conduct
The Tide project adheres to the Contributor Covenant Code of Conduct. This describes the minimum behavior expected from all contributors.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Top Related Projects
Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
Ergonomic and modular web framework built with Tokio, Tower, and Hyper
A super-easy, composable, web server framework for warp speeds.
A web framework for Rust.
A flexible web framework that promotes stability, safety, security and speed.
An Extensible, Concurrent Web Framework for Rust
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot