async-trait

Type erasure for async fn in Rust traits, enabling async methods behind dyn dispatch.

Library
Cargo
v0.1.92
2,208 stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
69 /100 Good
Development Activity 56
Maintenance 72
Community 48
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
91 /100 Excellent
Architecture 90
Code Quality 92
Innovation 93
Learning Curve 88

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 as dyn Trait.
  • A #[async_trait(?Send)] variant for futures that do not need to be Send.
  • Full support for self by value/ref/mut-ref, generics, lifetimes, associated types, and default method implementations, with no unsafe in 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 43 apps in this directory

TypeScript
67%
Apache 2.0

tabularis

Databases · Developer Tools

5,270

Open-source desktop SQL workspace with built-in PostgreSQL, MySQL, and SQLite drivers, SQL notebooks, a visual query builder, and a built-in MCP server for AI agents like Claude and Cursor.

View details
84
Repo Health
89
Technical
66
Dependency
Built with
TypeScript 67%
Rust 31%
Updated 5 days ago
Rust
66%
Apache 2.0

Temps

Analytics · Devops · Monitoring

865

A self-hosted Rust PaaS that replaces Vercel, Sentry, PostHog, Pingdom, Resend, and E2B with one binary — plus 440+ CLI operations agents like Claude Code can drive directly.

View details
81
Repo Health
86
Technical
66
Dependency
Built with
Rust 66%
TypeScript 33%
Updated 6 days ago
Rust
79%
Apache 2.0

TensorZero

Ab Testing Experimentation · AI Development · Monitoring

11,708

TensorZero unifies the LLM gateway, observability, evaluation, optimization, and experimentation stack behind a single OpenAI-compatible API, built in Rust for sub-millisecond p99 latency.

View details
53
Repo Health
87
Technical
68
Dependency
Built with
Rust 79%
TypeScript 15%
Updated 4 months ago
Rust
50%
Apache 2.0

Vibe Kanban

AI Agents · AI Code Assistants · Project Management

28,441

A kanban board for planning work and dispatching Claude Code, Codex, Gemini CLI, and eight other coding agents into isolated git worktrees, then reviewing and merging their diffs from one UI.

View details
72
Repo Health
75
Technical
63
Dependency
Built with
Rust 50%
TypeScript 46%
Updated 1 months ago
TypeScript
95%
Apache 2.0

Void

AI Code Assistants · Automation · Code Editors

28,733

Open-source AI code editor with direct LLM integration and data privacy

View details
44
Repo Health
84
Technical
68
Dependency
Built with
TypeScript 95%
Updated 4 months ago
Rust
97%
Apache 2.0

Volga

Data Engineering

161

A Rust-based real-time data processing engine for AI/ML feature computation, built on Apache DataFusion and Arrow — positioned as an alternative to Flink, Spark, Chronon, and OpenMLDB with unified streaming, batch, and request-time execution.

View details
61
Repo Health
67
Technical
72
Dependency
Built with
Rust 97%
Updated 1 months ago
Python
66%
Apache 2.0

WrenAI

AI Agents · Analytics · Data Engineering

17,958

Open-source GenBI engine that lets AI agents turn natural-language questions into governed SQL, charts, and shareable dashboards across 20+ data sources — no vendor lock-in, no black-box prompts.

View details
91
Repo Health
91
Technical
68
Dependency
Built with
Python 66%
Rust 31%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers