async-recursion
A Rust procedural macro that makes recursive async functions compile by boxing their returned Future.
Repository Health
Technical Analysis
async-recursion is a small but essential Rust procedural macro that lets you write recursive async fns. Rust’s compiler rejects a directly recursive async function because it would produce an infinitely sized Future; it even suggests this crate by name in the error message.
Applying the #[async_recursion] attribute automatically rewrites the function to return a boxed dyn Future, breaking the size cycle. It offers ?Send and Sync options to control the auto-trait bounds on the returned future, so it fits both single-threaded and multi-threaded async runtimes.
What You Get
- The
#[async_recursion]attribute macro for recursive async functions - Automatic boxing of the returned Future to satisfy the compiler
- A
?Sendoption to drop theSendbound for single-threaded runtimes - A
Syncoption to add aSyncbound when needed - A tiny, dependency-light crate that just works with any async runtime
Common Use Cases
- Recursively traversing trees or graphs in async code
- Async parsers and interpreters that call themselves on sub-expressions
- Divide-and-conquer async algorithms that await recursive calls
- Walking nested data structures where each level performs async I/O
Under The Hood
Architecture
The crate is a procedural macro (proc-macro = true) that parses the annotated function with syn, then rewrites its signature to return Pin<Box<dyn Future<Output = ...> + Send + 'async_recursion>> and wraps the original body in an async block boxed with Box::pin. The Send/Sync auto-trait bounds are added or removed based on the ?Send and Sync attribute arguments, and lifetimes are threaded through so borrowed parameters remain valid across the boxed future. Code generation is emitted with quote.
Tech Stack
Pure Rust, ~31KB, built on the standard proc-macro trio: syn for parsing, quote for code generation, and proc-macro2 for token handling. It has no runtime dependencies and is compatible with any executor (Tokio, async-std, smol) since it only produces standard boxed futures.
Code Quality
Despite its small size the crate is extremely widely used (over 120 million downloads) and stable, with a focused test suite exercising the macro expansions across the Send/?Send/Sync variants and lifetime edge cases. Its longevity and adoption since 2019, plus being namechecked by the Rust compiler itself, make it a de-facto standard.
API Design
The API is about as ergonomic as possible: one attribute, no code changes at call sites, and two optional flags for the rare cases where the default Send/!Sync bounds don’t fit. The README’s fibonacci example and the compiler’s own suggestion make discovery and adoption effortless.
Used by 2 apps in this directory
CubeSandbox
Developer Tools · Security · AI Agents
Instant, concurrent, hardware-isolated MicroVM sandboxes for AI agents — E2B-API compatible, sub-60ms cold starts, and a built-in zero-trust egress proxy, all self-hostable at scale.
Hook0
Devops
Open-source Webhooks-as-a-Service: deliver events to your users with auto-retry, signed payloads, and a real-time subscriber dashboard — all without building the infrastructure yourself.