async-trait
Type erasure for async fn in Rust traits, enabling async methods behind dyn dispatch.
Repository Health
Technical Analysis
async-trait is a Rust procedural-macro crate that makes it possible to write async fn inside traits and use those traits as dyn Trait objects. Although Rust 1.75 stabilized async functions in traits, it still does not allow such traits to be object-safe, which breaks common patterns like storing heterogeneous handlers in a Vec<Box<dyn Trait>>.
The crate solves this with a single #[async_trait] attribute macro applied to a trait and its impls. Under the hood it rewrites each async method into one that returns a boxed, type-erased Pin<Box<dyn Future + Send>>, so the trait becomes dyn-compatible again with no unsafe code in the generated output.
What You Get
- A single
#[async_trait]attribute macro that works on both trait definitions and impl blocks. - Automatic transformation of async methods into
Pin<Box<dyn Future + Send + 'async_trait>>returns, making the trait usable asdyn Trait. - A
#[async_trait(?Send)]variant for futures that do not need to beSend. - Full support for self by value/ref/mut-ref, generics, lifetimes, associated types, and default method implementations, with no
unsafein generated code.
Common Use Cases
- Defining trait-based plugin or handler interfaces where implementations are stored behind
Box<dyn Trait>or&dyn Trait. - Building async service abstractions (repositories, clients, middleware) that must be object-safe for dynamic dispatch.
- Maintaining libraries that need to support async trait methods across older Rust toolchains and dyn use cases the native feature does not yet cover.
Under The Hood
Architecture
The crate is a proc-macro ([lib] proc-macro = true) whose entry point in src/lib.rs is the #[proc_macro_attribute] async_trait function. It parses the annotated item into an Item::Trait or Item::Impl (src/parse.rs) and dispatches to expand() in src/expand.rs, the ~500-line core that rewrites each async method. The transform relies on syn’s VisitMut visitor pattern across focused modules: src/receiver.rs detects and rewrites self usage (ReplaceSelf, has_self_in_sig), src/lifetime.rs collects and injects the synthetic 'async_trait lifetime, and src/bound.rs infers Send/Sync supertrait bounds. Each async fn body is wrapped in Box::pin(async move { ... }) returning Pin<Box<dyn Future + Send + 'async_trait>>.
Tech Stack
Pure Rust (edition 2021, MSRV 1.71) with the standard proc-macro toolchain: proc-macro2, quote for token generation, and syn v3 with the full, visit-mut, parsing, and printing features for AST manipulation. A minimal build.rs only declares a cfg for nightly test gating. Dev-dependencies include futures, tracing/tracing-attributes, rustversion, and trybuild for compile-fail testing.
Code Quality
The code is idiomatic and cleanly separated by concern, with each transformation step in its own module. Testing is thorough: tests/test.rs contains 205 test functions exercising receivers, generics, lifetimes, and associated types, backed by a custom executor harness and an extensive tests/ui suite of trybuild compile-fail cases with expected .stderr output. The generated expansion contains no unsafe, an explicit safety guarantee stated in the README.
API Design
The public surface is a single attribute macro, making adoption nearly frictionless: annotate the trait and its impls, keep writing ordinary async fn, and the trait becomes dyn-compatible. The #[async_trait(?Send)] toggle cleanly covers the non-thread-safe case. Documentation is excellent, with a worked example, an explanation of the desugaring, and guidance on lifetime-elision pitfalls in both the README and the rustdoc on docs.rs.
Used by 37 apps in this directory
cocoindex
Data Engineering · AI Development
An incremental data indexing engine that keeps AI agent context perpetually fresh by reprocessing only what changed.
Cog
AI Development · Devops · Developer Tools
An open-source CLI that packages machine learning models into standard, production-ready Docker containers — no Dockerfile wrangling, no CUDA version hell.
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.
Enso
Analytics · Data Engineering · Low Code Platforms
A visual and textual programming platform for data prep and analysis where the node graph and the underlying Enso code are always perfectly in sync, built by an Alteryx co-founder on a GraalVM engine.
headroom
AI Development · Developer Tools
Compress everything your AI agent reads — tool outputs, logs, RAG chunks, and files — before it reaches the LLM, achieving 60–95% fewer tokens with the same answers.
helix-db
Databases
A graph-vector database built from scratch in Rust that unifies graph traversal, vector search, key-value, and relational storage into a single platform for AI applications.
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.
hoop
Security · Monitoring
A wire-protocol gateway that enforces data masking, command blocking, approval workflows, and full session recording for engineers and AI agents accessing production infrastructure.
iii
Developer Tools · Devops
Compose, extend, and observe every backend service in real time using three primitives: Workers, Functions, and Triggers.