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.

Like NestJS: Decorators, DI, modules, guards, interceptors
Like Express: Middleware chain, flexible routing, simple API
Like Koa: Async/await first, context objects, composable middleware

Evaluating Rust Frameworks?

Armature stands alongside Actix-web, Rocket, Axum, and Warp but with a unique focus on Angular/NestJS-style architecture.

vs. Actix-web: Higher-level abstractions, built-in DI container
vs. Rocket: Module-based architecture, more enterprise features
vs. Axum: Decorator syntax, integrated auth/validation/caching
vs. Warp: Less combinator complexity, familiar MVC structure

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)

Actix-web
500K
Rust/Tokio
Axum
425K
Rust/Tokio
Warp
375K
Rust/Tokio
Armature
385K
Rust/Tokio
Rocket
275K
Rust/Tokio
Koa
43K
Node.js
Express
38K
Node.js
NestJS
33K
Node.js
Next.js
28K
Node.js

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

Memory Usage (MB)

Idle Memory

Actix-web
8MB
Axum
10MB
Warp
9MB
Armature
10MB
Rocket
15MB
Koa
32MB
Express
40MB
NestJS
65MB
Next.js
85MB

Lower is better

Under Load (50 connections)

Actix-web
25MB
Axum
30MB
Warp
28MB
Armature
28MB
Rocket
40MB
Koa
90MB
Express
115MB
NestJS
150MB
Next.js
180MB

Lower is better

10-15x
Faster than Node.js
Armature vs Express/NestJS
~3x
Less Memory
Compared to Node.js frameworks
<1ms
p99 Latency
Armature optimized

Internal Micro-Benchmarks

Criterion benchmarks measuring individual operations. Negative percentages indicate improvement from previous versions.

Route Matching

10 routes - first match
52ns -10%
10 routes - middle match
139ns -9%
100 routes - first match
51ns -6%
100 routes - middle match
343ns -17%
500 routes - not found
6.8µs -20%

Handler Invocation

Simple handler
107ns -6%
JSON handler
174ns stable
Path param handler
290ns -3%
Body handler
521ns stable

Full Request Cycle

Health check
386ns -4%
GET with param
692ns -15%
POST with body
778ns -26%

JSON Serialization

Serialize small
17ns -14%
Serialize large
14.4µs -7%
Deserialize medium
204ns -2%

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

A

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.

X

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.

W

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

Armature - NestJS-style
#[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))
    }
}
Actix-web - Handler functions
#[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)
Axum - Extractor-based
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))
Rocket - Attribute macros
#[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