Top Related Projects
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Zero-cost asynchronous programming in Rust
A small and fast async runtime for Rust
Actor framework for Rust.
An HTTP library for Rust
async fn(Request) -> Result<Response, Error>
Quick Overview
Async-std is a Rust library that provides asynchronous versions of the Rust standard library. It aims to make asynchronous programming in Rust more accessible and familiar by mirroring the standard library's API while offering non-blocking alternatives.
Pros
- Familiar API design, closely resembling Rust's standard library
- Comprehensive set of asynchronous primitives and utilities
- Well-documented and actively maintained
- Supports both single-threaded and multi-threaded runtimes
Cons
- May have slightly higher overhead compared to more specialized async libraries
- Learning curve for developers new to asynchronous programming
- Some features might not be as optimized as in more focused libraries
- Occasional breaking changes during major version updates
Code Examples
- Asynchronous file reading:
use async_std::fs::File;
use async_std::prelude::*;
async fn read_file(path: &str) -> std::io::Result<String> {
let mut file = File::open(path).await?;
let mut contents = String::new();
file.read_to_string(&mut contents).await?;
Ok(contents)
}
- Asynchronous TCP server:
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
async fn handle_client(mut stream: TcpStream) -> std::io::Result<()> {
let mut buffer = [0; 1024];
stream.read(&mut buffer).await?;
stream.write_all(&buffer).await?;
Ok(())
}
async fn run_server() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
let stream = stream?;
task::spawn(handle_client(stream));
}
Ok(())
}
- Asynchronous HTTP request:
use async_std::prelude::*;
use async_std::net::TcpStream;
async fn fetch_url(url: &str) -> std::io::Result<String> {
let mut stream = TcpStream::connect(url).await?;
let request = format!("GET / HTTP/1.1\r\nHost: {}\r\n\r\n", url);
stream.write_all(request.as_bytes()).await?;
let mut response = String::new();
stream.read_to_string(&mut response).await?;
Ok(response)
}
Getting Started
To use async-std in your Rust project, add the following to your Cargo.toml
:
[dependencies]
async-std = "1.12.0"
Then, in your Rust code, you can import and use async-std:
use async_std::prelude::*;
use async_std::task;
fn main() {
task::block_on(async {
println!("Hello, async world!");
})
}
This example creates a simple asynchronous task that prints a message. You can run this code using cargo run
.
Competitor Comparisons
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Pros of tokio
- More mature and widely adopted in the Rust ecosystem
- Offers a broader range of features and utilities
- Generally better performance for high-concurrency scenarios
Cons of tokio
- Steeper learning curve due to more complex API
- Heavier runtime with more overhead for simple use cases
- Less intuitive for developers coming from synchronous programming
Code Comparison
tokio:
#[tokio::main]
async fn main() {
println!("Hello from tokio!");
tokio::time::sleep(Duration::from_secs(1)).await;
}
async-std:
#[async_std::main]
async fn main() {
println!("Hello from async-std!");
async_std::task::sleep(Duration::from_secs(1)).await;
}
Both tokio and async-std are popular asynchronous runtime libraries for Rust, offering similar core functionality. tokio is more established and feature-rich, making it suitable for complex applications and high-performance scenarios. async-std, on the other hand, aims for simplicity and ease of use, making it a good choice for smaller projects or developers new to asynchronous programming.
The code comparison shows that both libraries have similar syntax for basic operations, with minor differences in module names and attribute macros. The choice between them often depends on specific project requirements, team expertise, and performance needs.
Zero-cost asynchronous programming in Rust
Pros of futures-rs
- More low-level and flexible, allowing for fine-grained control over async operations
- Provides core async primitives that other libraries can build upon
- Closely aligned with the Rust language's async/await syntax and ecosystem
Cons of futures-rs
- Steeper learning curve due to its lower-level nature
- Requires more boilerplate code for common async tasks
- Less comprehensive standard library-like functionality compared to async-std
Code Comparison
futures-rs:
use futures::executor::block_on;
use futures::future::Future;
async fn hello_world() -> String {
"Hello, world!".to_string()
}
let future = hello_world();
let result = block_on(future);
async-std:
use async_std::task;
async fn hello_world() -> String {
"Hello, world!".to_string()
}
task::block_on(async {
let result = hello_world().await;
println!("{}", result);
});
The code comparison shows that futures-rs requires explicit use of an executor and future handling, while async-std provides a more streamlined approach with its task module. async-std's API is designed to be more similar to Rust's standard library, making it easier for developers familiar with synchronous Rust to transition to asynchronous programming.
A small and fast async runtime for Rust
Pros of smol
- Lightweight and minimalistic design, resulting in a smaller footprint
- Faster compilation times due to fewer dependencies
- More flexible and customizable, allowing users to choose specific components
Cons of smol
- Less comprehensive documentation compared to async-std
- Fewer built-in features and utilities out of the box
- Potentially steeper learning curve for beginners due to its minimalistic approach
Code Comparison
smol example:
use smol::io;
use smol::prelude::*;
async fn example() -> io::Result<()> {
let mut stream = smol::net::TcpStream::connect("example.com:80").await?;
stream.write_all(b"GET / HTTP/1.1\r\n\r\n").await?;
Ok(())
}
async-std example:
use async_std::prelude::*;
use async_std::net::TcpStream;
async fn example() -> std::io::Result<()> {
let mut stream = TcpStream::connect("example.com:80").await?;
stream.write_all(b"GET / HTTP/1.1\r\n\r\n").await?;
Ok(())
}
Both smol and async-std provide asynchronous runtime implementations for Rust, but they differ in their approach and feature set. smol focuses on simplicity and flexibility, while async-std aims to provide a more comprehensive standard library-like experience for asynchronous programming. The choice between the two depends on project requirements, developer preferences, and the desired level of abstraction and built-in functionality.
Actor framework for Rust.
Pros of actix
- Higher performance and lower latency for web applications
- More mature ecosystem with additional features like WebSockets and HTTP/2 support
- Stronger focus on web development, providing a full-featured web framework
Cons of actix
- Steeper learning curve due to more complex API and concepts
- Less flexible for general-purpose asynchronous programming tasks
- Historically had some safety concerns (though largely addressed in recent versions)
Code Comparison
actix 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
}
async-std example:
use async_std::task;
use tide::Request;
async fn hello(_req: 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 examples demonstrate a simple HTTP server setup, but actix provides a more specialized web framework, while async-std uses the Tide framework for web functionality, showcasing its general-purpose nature.
An HTTP library for Rust
Pros of hyper
- Specialized for HTTP: Hyper is specifically designed for HTTP/1 and HTTP/2, making it highly optimized for web-related tasks
- Mature and widely adopted: Hyper has been around longer and is used in many production environments
- Extensive ecosystem: Offers a rich set of tools and integrations for building HTTP clients and servers
Cons of hyper
- Limited scope: Focuses solely on HTTP, while async-std provides a more general-purpose async runtime
- Steeper learning curve: May require more in-depth knowledge of HTTP protocols compared to async-std's broader approach
- Less flexibility: Might be overkill for simple networking tasks that don't require full HTTP functionality
Code comparison
async-std example:
use async_std::net::TcpStream;
use async_std::prelude::*;
async fn fetch(url: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut stream = TcpStream::connect(url).await?;
let mut buffer = String::new();
stream.read_to_string(&mut buffer).await?;
Ok(buffer)
}
hyper example:
use hyper::{Client, Uri};
async fn fetch(url: &str) -> Result<String, Box<dyn std::error::Error>> {
let client = Client::new();
let uri = url.parse::<Uri>()?;
let resp = client.get(uri).await?;
let body_bytes = hyper::body::to_bytes(resp.into_body()).await?;
Ok(String::from_utf8(body_bytes.to_vec())?)
}
async fn(Request) -> Result<Response, Error>
Pros of Tower
- Modular middleware system for building robust client and server applications
- Focuses on service composition and abstraction, allowing for flexible and reusable components
- Provides a rich ecosystem of middleware and utilities for common networking tasks
Cons of Tower
- Steeper learning curve due to its more abstract and composable nature
- Less comprehensive standard library compared to async-std
- May require more boilerplate code for simple use cases
Code Comparison
Tower example:
use tower::{Service, ServiceBuilder, ServiceExt};
let service = ServiceBuilder::new()
.rate_limit(5, std::time::Duration::from_secs(1))
.service_fn(|request: String| async move { Ok(request.len()) });
async-std example:
use async_std::task;
use async_std::net::TcpListener;
task::block_on(async {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
println!("Listening on {}", listener.local_addr()?);
})
Tower is more focused on building composable services with middleware, while async-std provides a broader set of asynchronous primitives and utilities for general-purpose async programming. Tower excels in scenarios requiring complex service composition, while async-std offers a more familiar and comprehensive standard library-like experience for async Rust development.
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
async-std
API Docs | Book | Releases | Contributing
This crate provides an async version of std
. It provides all the interfaces
you are used to, but in an async version and ready for Rust's async
/await
syntax.
Features
- Modern: Built from the ground up for
std::future
andasync/await
with blazing fast compilation time. - Fast: Our robust allocator and threadpool designs provide ultra-high throughput with predictably low latency.
- Intuitive: Complete parity with the stdlib means you only need to learn APIs once.
- Clear: Detailed documentation and accessible guides mean using async Rust was never easier.
Examples
use async_std::task;
async fn say_hello() {
println!("Hello, world!");
}
fn main() {
task::block_on(say_hello())
}
More examples, including networking and file access, can be found in our
examples
directory and in our documentation.
Philosophy
We believe Async Rust should be as easy to pick up as Sync Rust. We also believe that the best API is the one you already know. And finally, we believe that providing an asynchronous counterpart to the standard library is the best way stdlib provides a reliable basis for both performance and productivity.
Async-std is the embodiment of that vision. It combines single-allocation task creation, with an adaptive lock-free executor, threadpool and network driver to create a smooth system that processes work at a high pace with low latency, using Rust's familiar stdlib API.
Installation
Run this in your projects folder:
$ cargo add async-std
We also provide a set of "unstable" features with async-std. See the features documentation on how to enable them.
Ecosystem
-
async-tls â Async TLS/SSL streams using Rustls.
-
async-native-tls â Native TLS for Async. Native TLS for futures and async-std.
-
async-tungstenite â Asynchronous WebSockets for async-std, tokio, gio and any std Futures runtime.
-
Tide â Serve the web. A modular web framework built around async/await.
-
SQLx â The Rust SQL Toolkit. SQLx is a 100% safe Rust library for Postgres and MySQL with compile-time checked queries.
-
Surf â Surf the web. Surf is a friendly HTTP client built for casual Rustaceans and veterans alike.
-
Xactor â Xactor is a rust actors framework based on async-std.
-
async-graphql â A GraphQL server library implemented in rust, with full support for async/await.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate 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
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Zero-cost asynchronous programming in Rust
A small and fast async runtime for Rust
Actor framework for Rust.
An HTTP library for Rust
async fn(Request) -> Result<Response, Error>
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