Why Armature?
Love the developer experience of NestJS or Express but want Rust's performance and safety? Armature brings familiar patterns to the Rust ecosystem.
Coming from Node.js?
If you've used NestJS, Express, or Koa, you'll feel right at home with Armature's decorator-based approach and middleware system.
Evaluating Rust Frameworks?
Armature stands alongside Actix-web, Rocket, Axum, and Warp but with a unique focus on Angular/NestJS-style architecture.
Framework Comparisons
A detailed comparison of Armature against the most popular Rust web frameworks
| Feature | Armature | Actix-web | Axum | Rocket | Warp |
|---|---|---|---|---|---|
| Architecture | |||||
| Dependency Injection | ✓ Built-in | ✗ | ~ Extension | ✗ | ✗ |
| Module System | ✓ NestJS-style | ✗ | ✗ | ✗ | ✗ |
| Decorators/Attributes | ✓ Proc macros | ~ Limited | ✗ | ✓ | ✗ |
| Guards/Interceptors | ✓ Built-in | ~ Middleware | ~ Tower layers | ~ Fairings | ~ Filters |
| Lifecycle Hooks | ✓ OnInit, OnDestroy | ✗ | ✗ | ~ Fairings | ✗ |
| Built-in Features | |||||
| Authentication (JWT) | ✓ Built-in | ~ actix-jwt | ~ axum-jwt | ~ rocket_jwt | ✗ |
| OAuth2/OIDC | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
| SAML | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
| Validation | ✓ Built-in | ~ validator | ~ validator | ~ validator | ~ validator |
| OpenAPI/Swagger | ✓ Built-in | ~ utoipa | ~ utoipa | ~ okapi | ✗ |
| GraphQL | ✓ Built-in | ~ async-graphql | ~ async-graphql | ~ juniper | ~ async-graphql |
| Job Queues | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
| Cron Scheduler | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
| Caching | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
| Rate Limiting | ✓ Built-in | ~ actix-ratelimit | ~ tower | ✗ | ✗ |
| Security Headers | ✓ Built-in | ✗ | ✗ | ~ rocket_helmet | ✗ |
| ACME/Let's Encrypt | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
| Observability | |||||
| OpenTelemetry | ✓ Built-in | ~ tracing | ~ tracing | ~ tracing | ~ tracing |
| Structured Logging | ✓ Built-in | ~ tracing | ~ tracing | ~ tracing | ~ tracing |
| Developer Experience | |||||
| CLI Tool | ✓ armature-cli | ✗ | ✗ | ✗ | ✗ |
| Code Generation | ✓ Controllers, etc. | ✗ | ✗ | ✗ | ✗ |
| Project Templates | ✓ 4 templates | ✗ | ✗ | ✗ | ✗ |
| Hot Reload | ✓ armature dev | ~ cargo-watch | ~ cargo-watch | ~ cargo-watch | ~ cargo-watch |
✓ = Built-in ~ = Available via external crate ✗ = Not available
Performance Benchmarks
Real-world performance comparison across common API scenarios. Benchmarks run with 50 concurrent connections
over 10 seconds using oha.
Throughput (Requests/Second)
Higher is better • Plaintext response benchmark
Detailed Performance Comparison
| Framework | Runtime | Plaintext | JSON | Path Param | POST | Latency p50 | Latency p99 | vs Armature |
|---|---|---|---|---|---|---|---|---|
| Actix-web | Rust/Tokio | 500K/s | 375K/s | 320K/s | 280K/s | 0.08ms | 0.5ms | 1.3x faster |
| Axum | Rust/Tokio | 425K/s | 340K/s | 290K/s | 250K/s | 0.1ms | 0.6ms | 1.1x faster |
| Warp | Rust/Tokio | 375K/s | 300K/s | 260K/s | 220K/s | 0.12ms | 0.8ms | 1.0x slower |
| Armature | Rust/Tokio | 385K/s | 305K/s | 260K/s | 220K/s | 0.11ms | 0.7ms | baseline |
| Rocket | Rust/Tokio | 275K/s | 200K/s | 170K/s | 120K/s | 0.18ms | 1.5ms | 1.4x slower |
| Koa | Node.js | 43K/s | 38K/s | 35K/s | 29K/s | 2.5ms | 8ms | 9.1x slower |
| Express | Node.js | 38K/s | 33K/s | 29K/s | 25K/s | 3ms | 10ms | 10.3x slower |
| NestJS | Node.js | 33K/s | 29K/s | 25K/s | 21K/s | 3.5ms | 12ms | 11.8x slower |
| Next.js | Node.js | 28K/s | 24K/s | 20K/s | 17K/s | 4ms | 15ms | 14.0x slower |
| Actix-web | Rust/Tokio | 500K/s | 375K/s | 320K/s | 280K/s | 0.08ms | 0.5ms | 1.3x faster |
| Axum | Rust/Tokio | 425K/s | 340K/s | 290K/s | 250K/s | 0.1ms | 0.6ms | 1.1x faster |
| Warp | Rust/Tokio | 375K/s | 300K/s | 260K/s | 220K/s | 0.12ms | 0.8ms | 1.0x slower |
| Armature | Rust/Tokio | 385K/s | 305K/s | 260K/s | 220K/s | 0.11ms | 0.7ms | baseline |
| Rocket | Rust/Tokio | 275K/s | 200K/s | 170K/s | 120K/s | 0.18ms | 1.5ms | 1.4x slower |
| Koa | Node.js | 43K/s | 38K/s | 35K/s | 29K/s | 2.5ms | 8ms | 9.1x slower |
| Express | Node.js | 38K/s | 33K/s | 29K/s | 25K/s | 3ms | 10ms | 10.3x slower |
| NestJS | Node.js | 33K/s | 29K/s | 25K/s | 21K/s | 3.5ms | 12ms | 11.8x slower |
| Next.js | Node.js | 28K/s | 24K/s | 20K/s | 17K/s | 4ms | 15ms | 14.0x slower |
Memory Usage (MB)
Idle Memory
Lower is better
Under Load (50 connections)
Lower is better
Internal Micro-Benchmarks
Criterion benchmarks measuring individual operations. Negative percentages indicate improvement from previous versions.
Route Matching
Handler Invocation
Full Request Cycle
JSON Serialization
Benchmarks run with Criterion on Linux. Lower times are better. Last updated: December 2024.
Benchmark Methodology
Configuration:
- • 50 concurrent connections
- • 10-second duration per test
- • 2-second warmup period
- • Release/production builds
Endpoints Tested:
- •
GET /- Plaintext response - •
GET /json- JSON serialization - •
GET /users/:id- Path parameter -
•
POST /api/users- JSON body parsing
Results may vary based on hardware, OS, and configuration. Run your own benchmarks for accurate comparisons. View benchmark code →
Detailed Comparisons
Armature vs Actix-web
The performance king of Rust web frameworks
Actix-web Strengths
- ✓ Extremely high performance (often #1 in benchmarks)
- ✓ Mature ecosystem with many extensions
- ✓ Large community and extensive documentation
- ✓ Actor model for stateful services
Why Choose Armature
- → Built-in dependency injection container
- → Module system for organizing large codebases
- → Integrated auth, validation, caching, queues
- → CLI for code generation and scaffolding
Bottom line: Armature gives you Actix-level performance with NestJS-level productivity. Get the best of both worlds without sacrificing either.
Armature vs Axum
Tokio's official web framework
Axum Strengths
- ✓ Official Tokio ecosystem integration
- ✓ Tower middleware ecosystem compatibility
- ✓ Ergonomic extractors for type-safe handlers
- ✓ Minimal, composable design philosophy
Why Choose Armature
- → Decorator macros instead of function composition
- → Controllers and modules for code organization
- → Guards and interceptors (not just middleware)
- → Complete auth solution (JWT, OAuth2, SAML)
Bottom line: Armature builds on the same Tokio foundation but adds the structure and enterprise features you need for production applications.
Armature vs Rocket
The ergonomics-focused framework
Rocket Strengths
- ✓ Beautiful, intuitive macro-based routing
- ✓ Excellent compile-time error messages
- ✓ Request guards for type-safe access control
- ✓ Built-in templating and form handling
Why Choose Armature
- → Dependency injection for service management
- → Module system for organizing enterprise apps
- → More enterprise features out of the box
- → CLI tooling for code generation
Bottom line: Armature matches Rocket's beautiful macro syntax while adding dependency injection, modules, and all the enterprise features you'll eventually need.
Armature vs Warp
The filter-based composable framework
Warp Strengths
- ✓ Powerful filter combinator system
- ✓ Built on hyper for excellent performance
- ✓ Highly composable request handling
- ✓ Minimal runtime overhead
Why Choose Armature
- → Familiar MVC-style structure vs combinators
- → Less learning curve for NestJS/Express devs
- → Built-in enterprise features (auth, queues, etc.)
- → Clear separation of concerns with modules
Bottom line: Armature gives you the same composability with a cleaner, more intuitive API that your whole team can understand and maintain.
Code Comparison
See how the same REST endpoint looks across different frameworks
#[controller("/users")]
#[derive(Default, Clone)]
struct UserController;
impl UserController {
#[get("/:id")]
async fn get(req: HttpRequest)
-> Result<Json<User>, Error>
{
let id: u32 = req.param("id")
.unwrap().parse().unwrap();
let user = find_user(id).await?;
Ok(Json(user))
}
#[post("")]
async fn create(req: HttpRequest)
-> Result<Json<User>, Error>
{
let dto: CreateUser = req.json()?;
let user = create_user(dto).await?;
Ok(Json(user))
}
} #[get("/users/{id}")]
async fn get_user(
path: web::Path<u32>
) -> impl Responder {
let id = path.into_inner();
let user = find_user(id).await?;
HttpResponse::Ok().json(user)
}
#[post("/users")]
async fn create_user(
body: web::Json<CreateUser>
) -> impl Responder {
let user = create_user(body.0).await?;
HttpResponse::Created().json(user)
}
// In main:
App::new()
.service(get_user)
.service(create_user) async fn get_user(
Path(id): Path<u32>
) -> Result<Json<User>, AppError> {
let user = find_user(id).await?;
Ok(Json(user))
}
async fn create_user(
Json(dto): Json<CreateUser>
) -> Result<Json<User>, AppError> {
let user = create_user(dto).await?;
Ok(Json(user))
}
// In main:
Router::new()
.route("/users/:id", get(get_user))
.route("/users", post(create_user)) #[get("/users/<id>")]
async fn get_user(id: u32)
-> Result<Json<User>, Status>
{
let user = find_user(id).await
.map_err(|_| Status::NotFound)?;
Ok(Json(user))
}
#[post("/users", data = "<dto>")]
async fn create_user(dto: Json<CreateUser>)
-> Result<Json<User>, Status>
{
let user = create_user(dto.0).await?;
Ok(Json(user))
}
// In main:
rocket::build()
.mount("/", routes![get_user, create_user]) Who Should Use Armature?
Node.js Developers Moving to Rust
If you're coming from NestJS, Express, Fastify, or Koa and want Rust's performance without losing familiar patterns like decorators, dependency injection, and middleware chains - Armature is for you.
Enterprise Applications
Building microservices, APIs, or backend systems that need authentication (JWT, OAuth2, SAML), validation, caching, job queues, and observability out of the box? Armature includes all these enterprise features.
Rust Developers Wanting Higher Abstractions
Love Rust but find Actix-web, Rocket, or Axum too low-level? Armature provides a full-featured framework with modular architecture, reducing boilerplate while maintaining type safety.
Teams with Mixed Backgrounds
Have a team where some developers know Rust and others are coming from Node.js, Java, or .NET? Armature's familiar patterns (DI, modules, decorators) help bridge the gap and accelerate onboarding.
Quick Decision Guide
Choose Armature if you want...
- • NestJS/Angular-style architecture
- • Built-in DI, auth, validation, caching
- • CLI tooling and code generation
- • Enterprise features out of the box
Choose Actix-web if you want...
- • Maximum raw performance
- • Actor model for stateful services
- • Large ecosystem of extensions
- • Full control over architecture
Choose Axum if you want...
- • Tokio ecosystem integration
- • Tower middleware compatibility
- • Minimal, composable design
- • Type-safe extractors
Choose Rocket if you want...
- • Beautiful macro-based routing
- • Excellent error messages
- • Built-in templating
- • Developer ergonomics focus
Choose Warp if you want...
- • Filter-based composition
- • Functional programming style
- • Minimal runtime overhead
- • hyper-based performance
Not sure? Start with...
- • Armature if from Node.js
- • Axum if new to web in Rust
- • Actix-web if performance critical
- • Rocket if learning Rust