skills/team/rust-feature-slice/SKILL.md
Feature-based vertical-slice architecture for Rust using Axum routers, handler functions, and service traits. No DI framework — dependencies wired manually via Arc<dyn Trait> in Axum State. CQRS via trait separation: reader traits for queries, writer traits for commands. Use when scaffolding Rust features, creating Axum feature modules, adding service layers, or organizing Rust code by feature rather than technical layer. Not for microservice/inter-process boundaries — scopes to module organization within a single Rust binary.
npx skillsauth add michaelalber/ai-toolkit rust-feature-sliceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
"Organize code by what it does, not by what it is. A feature folder contains everything needed to deliver a capability — not everything that happens to be a handler." -- Adapted from Jimmy Bogard
"In Rust, there is no DI framework. There is ownership. Design your dependencies so that ownership is clear, and wiring becomes mechanical." -- Rust Architecture Principle
Vertical slice architecture in Rust organizes code by feature (domain capability) rather than technical layer (handlers, services, repositories). Each feature is a Rust module containing everything needed to deliver that capability: router, handlers, service trait, service implementation, request/response types, and tests.
Rust has no dependency injection framework. Dependencies are wired manually using Arc<dyn Trait> stored in Axum's State<AppState>. This is not a limitation — it is explicit, compile-time-verified dependency wiring. The AppState struct is the composition root.
CQRS in Rust is a naming convention enforced by trait design: OrderReader (query methods) and OrderWriter (command methods) are separate traits, potentially implemented by the same struct. This separation makes the read/write boundary explicit without requiring a library.
Non-Negotiable Constraints:
use crate::features::other_feature:: in handlers. Features communicate through shared types in a common or domain module, not through direct imports.Arc<dyn OrderService> in AppState, not Arc<OrderServiceImpl>. This enables testing with mock implementations.Arc<dyn Trait> for shared state — not Mutex<ConcreteType>. The trait defines the contract; the Arc provides shared ownership.Result<T, AppError> on all handlers — handlers return Result<impl IntoResponse, AppError>. No panics, no unwrap in handler code.The 10 domain principles, the knowledge-base lookup map, and the anti-pattern catalog live in
references/principles-and-anti-patterns.md. The AI discipline rules (trait-not-concrete-in-state,
thin handlers, async-trait selection) and error-recovery procedures live in
references/discipline-and-recovery.md.
DETECT (before scaffolding)
[ ] Check for existing AppState struct (src/state.rs or src/app.rs)
[ ] Check for existing features/ directory structure
[ ] Identify Rust edition and async runtime (Cargo.toml)
[ ] Check for existing error types (AppError)
[ ] Identify database access pattern (SQLx, Diesel, none)
|
v
SCAFFOLD (create feature module)
[ ] Create src/features/<name>/mod.rs (re-exports)
[ ] Create src/features/<name>/router.rs (Axum Router with State)
[ ] Create src/features/<name>/service.rs (trait + impl)
[ ] Create src/features/<name>/models.rs (request/response types)
[ ] Create src/features/<name>/errors.rs (feature error type)
[ ] Create tests/features/<name>/integration_test.rs
|
v
REGISTER (wire into app)
[ ] Add service to AppState struct
[ ] Add Arc<dyn Trait> initialization in app startup
[ ] Merge feature Router into main app Router
[ ] Add From<FeatureError> for AppError
|
v
VERIFY
[ ] cargo build (no errors)
[ ] cargo test (all tests pass)
[ ] cargo clippy -- -D warnings (no warnings)
Exit criteria: Feature module created, registered in app, tests pass, Clippy clean.
<rust-feature-slice-state>
phase: DETECT | SCAFFOLD | REGISTER | VERIFY | COMPLETE
feature_name: [name]
edition: [2015 | 2018 | 2021 | 2024]
async_runtime: [tokio | async-std | none]
app_state_exists: [true | false]
features_dir_exists: [true | false]
app_error_exists: [true | false]
files_created: [comma-separated list]
build_status: [pass | fail | not-run]
test_status: [pass | fail | not-run]
last_action: [description]
next_action: [description]
</rust-feature-slice-state>
The scaffold reports the files it creates and modifies, then a verification gate:
## Rust Feature Slice Scaffold: [feature-name]
### Files to Create
- [ ] `src/features/[name]/{mod,router,service,models,errors}.rs`
- [ ] `tests/features/[name]/integration_test.rs`
### Files to Modify
- [ ] `src/state.rs` — add `Arc<dyn [Name]Service>` field
- [ ] `src/app.rs` or `src/main.rs` — merge feature Router, initialize service
- [ ] `src/errors.rs` — add `From<[Name]Error> for AppError`
### Verification
- [ ] `cargo build` · `cargo test` · `cargo clippy -- -D warnings` all pass
Full, ready-to-fill code for every file (mod/models/errors/service/router, AppState, AppError,
integration test) is in references/feature-module-template.md. The five Axum state-injection
patterns (single state, FromRef, nested state, Extension vs State, mock injection) are in
references/state-injection-patterns.md.
| Skill | Relationship |
|-------|-------------|
| axum-scaffolder | Provides the HTTP layer patterns (middleware, OpenAPI, auth). Use rust-feature-slice for module organization; use axum-scaffolder for HTTP infrastructure. |
| sqlx-migration-manager | When the feature requires database access, sqlx-migration-manager provides the safe migration and query patterns for the service implementation. |
| rust-architecture-checklist | After scaffolding, run rust-architecture-checklist to verify the feature follows ownership, trait, and error handling conventions. |
| rust-security-review | After scaffolding, run rust-security-review to verify the feature's auth middleware, input validation, and error handling are secure. |
| dotnet-vertical-slice | Parallel skill for .NET/Blazor codebases. Same vertical slice philosophy; different ecosystem. |
development
Interviews the user relentlessly about a plan, decision, or idea — one question at a time, each with a recommended answer. Shared engine behind "grill-me" and "grill-with-docs". Use on any "grill" trigger phrase or to stress-test thinking. Do NOT use to build the plan; it ends at shared understanding, not implementation.
testing
Runs a relentless interview to sharpen a plan or design, capturing the decisions as ADRs and a glossary along the way. Use when the user wants to be grilled AND wants the session to leave durable domain documentation behind. Do NOT use for a throwaway stress-test with no artifacts; use grill-me instead.
tools
OWASP-based security review of Vue/TypeScript front-ends. Detects framework (Vite/Vue CLI/Nuxt), entry points, and data flows; scans the OWASP Top 10 (2025) mapped to Vue client-side risks (raw-HTML XSS via v-html, URL/protocol injection, bundled secrets, insecure token storage, dependency CVEs, missing CSP, open redirects, router guard bypass); emits an exec summary plus graded findings. Use to audit Vue for vulnerabilities. Not for architecture grading (vue-architecture-checklist).
tools
Analyzes legacy Vue codebases and produces actionable modernization plans. Primary migration paths include Options API to Composition API, Vue 2 to Vue 3, Vue CLI to Vite, JavaScript to TypeScript, Vue Test Utils/Karma/Mocha to Vitest + Vue Testing Library, legacy Vuex to Pinia, and removed-in-Vue-3 pattern cleanup (filters, event bus, `$listeners`). Does NOT perform the migration — assesses, quantifies risk, and plans.