async-std Primer
A focused walkthrough of the async-std runtime for Rust. This primer covers the executor model, task spawning, and the I/O surface that mirrors the standard library while staying cooperative and non-blocking under load.
1. Installing and bootstrapping
Add async-std to your manifest with the attributesfeature enabled. This unlocks the #[async_std::main] macro so you can write an async entry point without manually constructing an executor.
[dependencies]
async-std = { version = "1", features = ["attributes"] }
# src/main.rs
#[async_std::main]
async fn main() {
println!("hello from async-std");
}2. Spawning tasks and joining
Tasks are spawned via async_std::task::spawn. Each call returns a JoinHandle implementing Future, so you can .await the result inline. Use spawn_blockingfor CPU-heavy work that would otherwise stall the executor.
use async_std::task;
let handle = task::spawn(async {
let n: u64 = (1..=100).sum();
n
});
let total = handle.await;
assert_eq!(total, 5050);3. Async I/O that mirrors std
The killer feature of async-std is API parity with the standard library. Files, TCP streams, and channels follow the same shapes as std::*, but every method is a future. Reading a file becomes a non-blocking await, and the rest of the program continues to make progress while the syscall is in flight.
use async_std::fs::File;
use async_std::prelude::*;
let mut file = File::open("notes.md").await?;
let mut buf = String::new();
file.read_to_string(&mut buf).await?;
println!("{} bytes", buf.len());