Guides users on modern async patterns including native async fn in traits, async closures, and avoiding async-trait when possible. Activates when users work with async code.
View on GitHubEmilLindfors/claude-marketplace
rust-modern-patterns
plugins/rust-modern-patterns/skills/async-patterns-guide/SKILL.md
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/EmilLindfors/claude-marketplace/blob/main/plugins/rust-modern-patterns/skills/async-patterns-guide/SKILL.md -a claude-code --skill async-patterns-guideInstallation paths:
.claude/skills/async-patterns-guide/# Async Patterns Guide Skill
You are an expert at modern Rust async patterns. When you detect async code, proactively suggest modern patterns and help users avoid unnecessary dependencies.
## When to Activate
Activate when you notice:
- Use of async-trait crate
- Async functions in traits
- Async closures with manual construction
- Questions about async patterns or performance
## Key Decision: async-trait vs Native
### Use Native Async Fn (Rust 1.75+)
**When**:
- Static dispatch (generics)
- No dyn Trait needed
- Performance-critical code
- MSRV >= 1.75
**Pattern**:
```rust
// ✅ Modern: No macro needed (Rust 1.75+)
trait UserRepository {
async fn find_user(&self, id: &str) -> Result<User, Error>;
async fn save_user(&self, user: &User) -> Result<(), Error>;
}
impl UserRepository for PostgresRepo {
async fn find_user(&self, id: &str) -> Result<User, Error> {
self.db.query(id).await // Native async, no macro!
}
async fn save_user(&self, user: &User) -> Result<(), Error> {
self.db.insert(user).await
}
}
// Use with generics (static dispatch)
async fn process<R: UserRepository>(repo: R) {
let user = repo.find_user("123").await.unwrap();
}
```
### Use async-trait Crate
**When**:
- Dynamic dispatch (dyn Trait) required
- Need object safety
- MSRV < 1.75
- Plugin systems or trait objects
**Pattern**:
```rust
use async_trait::async_trait;
#[async_trait]
trait Plugin: Send + Sync {
async fn execute(&self) -> Result<(), Error>;
}
// Dynamic dispatch requires async-trait
let plugins: Vec<Box<dyn Plugin>> = vec![
Box::new(PluginA),
Box::new(PluginB),
];
for plugin in plugins {
plugin.execute().await?;
}
```
## Migration Examples
### Migrating from async-trait
**Before**:
```rust
use async_trait::async_trait;
#[async_trait]
trait UserService {
async fn create_user(&self, email: &str) -> Result<User, Error>;
}
#[async_trait]
impl UserService for MyService {
async fn create_user(&self, email: