Native throughput
~463k req/s on 2 cores, ~213k per core, sub-millisecond p99,
no GC pauses. The same hyper/tokio core as the fastest Rust web
frameworks — with a structure on top.
Native throughput
~463k req/s on 2 cores, ~213k per core, sub-millisecond p99,
no GC pauses. The same hyper/tokio core as the fastest Rust web
frameworks — with a structure on top.
An order of magnitude less RAM
~4 MB idle, ~6 MB under load — versus ~80–120 MB for an equivalent Node service. Smaller instances, higher density, a materially lighter cloud bill.
Boots in milliseconds
Each deployable is a static native binary with no runtime to warm up — autoscaling and cold starts stop hurting.
Types you don't fight
Rust types end to end — entity, DTO, route handler, dataloader, GraphQL
schema, OpenAPI doc. No any, no unknown, no as casts at the
boundaries, no runtime “undefined is not a function.”
Declarative, decorator-driven
#[module], #[controller], #[resolver], #[processor],
#[gateway], #[cron_job], #[mcp]. Wiring is declarative — you write
logic, not boilerplate.
Verified before it serves
The DI graph is checked at boot — a bad import fails startup with a clear error naming the missing wire. No reflection, no runtime “cannot resolve dependency” five minutes after deploy.
Secure & transactional by composition
Authn, authorization, row-level filtering, response masking, transaction scope — activated by importing a module, not by remembering to call them. Forgetting to redact a field becomes structurally hard.
Batteries included, opt-in by crate
HTTP, GraphQL, OpenAPI, WebSockets, Redis-backed queues, scheduling, an event bus, MCP, CASL-style authorization, health probes, OpenTelemetry — each an opt-in crate, so a worker compiles no HTTP stack at all.
The same “Hello World” service — a provider, a controller, a module — built
once in NestRS and once in NestJS 11 on Node.js 20, under identical wrk load
(2 cores, -t2 -c64 -d20s).
A minimal slice — a provider, a controller, and a #[module] that lists them.
The DI graph is built and verified at boot; each app under apps/ compiles to
its own native binary. For a full vertical slice (core port plus HTTP/GraphQL adapters), start with the
tutorial.
use nestrs_core::injectable;
#[injectable]#[derive(Default)]pub struct HelloService;
impl HelloService { pub fn greeting(&self) -> &'static str { "Hello World" }}use std::sync::Arc;use nestrs_http::{controller, routes};use super::service::HelloService;
#[controller(path = "/")]pub struct HelloController { #[inject] svc: Arc<HelloService>,}
#[routes]impl HelloController { #[get("/")] async fn hello(&self) -> &'static str { self.svc.greeting() }}use nestrs_core::module;use super::{controller::HelloController, service::HelloService};
#[module(providers = [HelloService, HelloController])]pub struct HelloModule;$ just dev app…2026-06-03T10:14:22.183Z INFO nestrs::http: bound 1 route on 0.0.0.0:3001
$ curl http://localhost:3001Hello WorldThe same inject-and-decorate model carries every surface — HTTP, GraphQL, WebSockets, queues, scheduled jobs, MCP. Jump to a transport: HTTP, GraphQL, WebSockets, Data, Security.
NestRS is built for microservice-shaped backends without the old ceremony — several deployables, one shared feature library, and no obligation to split into many repositories while the team is still small.
Entities, services, and policy are written once. Each runnable has a clear responsibility — some sit on a public edge (surfaces clients and partners call), others stay non-public (background work, off the request path). Processes stay lean; your own services stay loosely coupled (shared contracts and data, not chatty RPC, no platform team or mesh required to get started).
One monorepo, one feature library — who runs where; operational boundaries, not a rewrite of business logic.
Splitting by responsibility is only the first step. In production you scale horizontally per role — the same binary, more replicas when the pressure moves: API capacity follows demand, worker capacity follows queue depth. There is no single “scale the monolith” knob; each deployable gets its own replica count.
Issuers such as OAuth usually keep a small, steady footprint — scale where the load actually moves.
Alpha. The API still shifts, rough edges remain — NestRS is not production-ready yet. Stars and early feedback on Discussions shape what follows.