Skip to content
Development
Skill

/rust-project

Modern Rust project architecture guide for 2025. Use when creating Rust projects (CLI, web services, libraries). Covers workspace structure, error handling, async patterns, and idiomatic Rust best practices.

From plugin
spellbook
25893 skills10 agents
Install
$ npx -y skills add majiayu000/spellbook --skill rust-project --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/rust-project

Context preview

The summary Claude sees to decide when to auto-load this skill.

Modern Rust project architecture guide for 2025. Use when creating Rust projects (CLI, web services, libraries). Covers workspace structure, error handling, async patterns, and idiomatic Rust best practices.

SKILL.md

rust-project.SKILL.md
name: rust-project
description: Modern Rust project architecture guide for 2025. Use when creating Rust projects (CLI, web services, libraries). Covers workspace structure, error handling, async patterns, and idiomatic Rust best practices.

Rust Project Architecture

Core Principles

  • **Ownership-first** — Embrace borrow checker, no unnecessary clones
  • **Zero-cost abstractions** — Newtype, iterators, async/await
  • **Workspace for scale** — Use Cargo workspace for multi-crate projects
  • **Error precision** — thiserror for libs, anyhow for apps
  • **Async with Tokio** — Tokio runtime + tracing for observability
  • **No backwards compatibility** — Delete, don't deprecate. Change directly
  • **LiteLLM for LLM APIs** — Use LiteLLM proxy for all LLM integrations

---

No Backwards Compatibility

> **Delete unused code. Change directly. No compatibility layers.**

// ❌ BAD: Deprecated attribute kept around
#[deprecated(since = "0.2.0", note = "Use new_function instead")]
pub fn old_function() { ... }

// ❌ BAD: Type alias for renamed types
pub type OldName = NewName; // "for backwards compatibility"

// ❌ BAD: Unused parameters
fn process(_legacy: &str, data: &Data) { ... }

// ❌ BAD: Feature flags for old behavior
#[cfg(feature = "legacy")]
fn old_impl() { ... }

// ✅ GOOD: Just delete and update all usages
pub fn new_function() { ... }
// Then: Find & replace all old_function → new_function

// ✅ GOOD: Remove unused parameters entirely
fn process(data: &Data) { ... }

---

LiteLLM for LLM APIs

> **Use LiteLLM proxy. Don't call provider APIs directly.**

// src/llm.rs
use async_openai::{Client, config::OpenAIConfig};

pub fn create_client(base_url: &str, api_key: &str) -> Client<OpenAIConfig> {
    let config = OpenAIConfig::new()
        .with_api_base(base_url)  // LiteLLM proxy URL
        .with_api_key(api_key);
    Client::with_config(config)
}

// Usage: connect to LiteLLM, use any model
let client = create_client("http://localhost:4000", &api_key);
let request = CreateChatCompletionRequestArgs::default()
    .model("gpt-4o")  // or "claude-3-opus", "gemini-pro", etc.
    .messages(vec![...])
    .build()?;

---

Quick Start

1. Initialize Project

# Simple project
cargo new myapp
cd myapp

# Workspace project
mkdir myapp && cd myapp
cargo init --name app

2. Apply Tech Stack

| Layer | Recommendation | |-------|----------------| | Async Runtime | Tokio | | Web Framework | Axum | | Serialization | Serde | | ORM / Database | SeaORM (async, Active Record) | | CLI | Clap (derive) | | Error (lib) | thiserror | | Error (app) | anyhow | | Logging | tracing + tracing-subscriber | | HTTP Client | reqwest | | Config | config-rs |

Web Framework Selection

| Framework | Choose When | |-----------|-------------| | **Axum** (default) | Modern microservices, Tokio ecosystem, container deployment, Tower middleware | | Actix Web | Maximum throughput, WebSocket-heavy, mature ecosystem needed | | Rocket | Rapid prototyping, small teams, minimal boilerplate |

> Axum provides the best balance of performance, ergonomics, and Tokio integration for most projects.

Database / ORM Selection

| Library | Choose When | |---------|-------------| | **SeaORM** (default) | CRUD-heavy services, rapid development, async-first, cross-database testing | | SQLx | Raw SQL control, maximum performance, compile-time SQL validation | | Diesel | Compile-time type safety, stable schema, synchronous workloads |

> SeaORM is recommended for its Active Record ergonomics, native async support, and seamless Axum integration.

Version Strategy

> **Always use latest. Never pin in templates.**

[dependencies]
tokio = { version = "*", features = ["full"] }
axum = "*"
serde = { version = "*", features = ["derive"] }

# cargo update fetches latest compatible versions
# Cargo.lock ensures reproducible builds

3. Choose Project Structure

Simple Project (Single Crate)

myapp/
├── Cargo.toml
├── src/
│   ├── main.rs           # Entry point
│   ├── lib.rs            # Library root (optional)
│   ├── config.rs         # Configuration
│   ├── error.rs          # Error types
│   ├── handlers/         # HTTP handlers (web)
│   │   └── mod.rs
│   ├── services/         # Business logic
│   │   └── mod.rs
│   └── models/           # Domain types
│       └── mod.rs
├── tests/                # Integration tests
│   └── api_test.rs
└── benches/              # Benchmarks
    └── bench.rs

Workspace Project (Multi-Crate)

myapp/
├── Cargo.toml            # Workspace manifest
├── crates/
│   ├── app/              # Binary crate
│   │   ├── Cargo.toml
│   │   └── src/main.rs
│   ├── core/             # Business logic lib
│   │   ├── Cargo.toml
│   │   └── src/lib.rs
│   └── infra/            # Infrastructure lib
│       ├── Cargo.toml
│       └── src/lib.rs
├── config/
│   └── default.toml
└── Makefile

---

Architecture Layers

main.rs — Entry Point

Wire dependencies, start runtime. No business logic.

// src/main.rs
use anyhow::Result;
use sea_orm::Database;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize tracing
    tracing_subscriber::registry()
        .with(tracing_subscriber::fmt::layer())
        .init();

    // Load config
    let config = myapp::config::load()?;

    // Connect to database (SeaORM)
    let db = Database::connect(&config.database_url).await?;

    // Build application state
    let state = myapp::AppState::new(db);

    // Build router
    let app = myapp::router::build(state);

    // Run server
    let listener = tokio::net::TcpListener::bind(&config.listen_addr).await?;
    tracing::info!("listening on {}", config.listen_addr);
    axum::serve(listener, app).await?;

    Ok(())
}

lib.rs — Library Root

Re-export public API, define AppState.

// src/lib.rs
pub mod config;
pub mod db;
pub
Read more
Ships withspellbook

Cross-runtime skills for Claude Code, Codex, and multi-agent workflows.

Get the whole plugin

Other skills on spellbook.