Nidus
Nidus is a modular Rust backend framework for building explicit, production-ready services with typed dependency injection, module graphs, Axum routes, Tower middleware, validation, OpenAPI, observability, testing, and separately installable adapters. It composes Axum, Tower, Tokio, serde, tracing, garde, utoipa, SQLx adapters, cache adapters, and normal Cargo workflows instead of replacing them.
Install
Install the Nidus CLI from crates.io:
During local framework development, install the CLI from this checkout:
Application dependencies stay explicit:
[]
= { = "nidus-rs", = "1.0.10", = ["http", "config", "openapi", "validation"] }
For production observability through the facade:
= { = "nidus-rs", = "1.0.10", = ["observability", "events", "jobs", "otel"] }
For embedded dashboard introspection:
= { = "nidus-rs", = "1.0.10", = ["dashboard"] }
Official integrations are separate crates:
= { = "1.0.10", = ["sqlite"] }
= { = "1.0.10", = ["moka"] }
= { = "1.0.10", = ["health"] }
= { = "1.0.10", = ["health"] }
= { = "1.0.10", = ["postgres"] }
= "1.0.10"
= "1.0.10"
Which Crate Do I Install?
- Use
cargo-nidusforcargo nidus new, route inspection, graph inspection, and OpenAPI generation. - Use
nidus-rsas the application facade. Import it asnidusinCargo.toml. - Enable facade features such as
http,config,openapi,validation,auth,events,jobs,observability, andotelonly when the app needs them. - Add only the data, messaging, durable-job, and telemetry adapter crates the application uses; the facade does not pull them transitively.
- Depend on lower-level crates such as
nidus-coreornidus-httponly when building framework extensions.
Common Imports And Extension Traits
Use the prelude at application entrypoints:
use *;
The prelude is the recommended import because it keeps common app composition types and extension traits in scope:
NidusApplicationExtenablesNidus::create::<AppModule>().- The facade builder supports
.with_router(router)and.build_with_router(router)for composing manual Axum routes with module routes. ApplicationHttpExtremains available for lower-levelNidus::bootstrap::<AppModule>()?.with_router(router)composition.ApiDefaultsObservabilityExtenables.observability(&observability)and observability-aware API defaults when theobservabilityfeature is enabled.
Common Compile Errors
no method named with_routerafterNidus::bootstrap: importApplicationHttpExtornidus::prelude::*; afterNidus::create, call the builder's.with_router(router)before.build().await.no method named listenorno method named into_router: importNidusApplicationExtornidus::prelude::*.no method named observability: importApiDefaultsObservabilityExtornidus::prelude::*.
Learning Path
- Run
cargo nidus new hello-nidusand start the generated server. - Inspect the generated module, controller, and service with
cargo nidus routesandcargo nidus graph. - Add one feature controller or service with
cargo nidus generate. - Add
config,validation, oropenapiwhen the first real route needs it. - Add
nidus-sqlxornidus-cacheonly after the application has a real persistence or cache boundary.
Quickstart
use *;
;
async
Core Concepts
- Modules: explicit imports, providers, controllers, and exports.
- Providers: Rust types registered by type, with singleton, transient, request-scoped, lazy, optional, and factory patterns.
- Controllers: Axum-backed route composition with Nidus route metadata.
- Guards and pipes: explicit authorization and validation boundaries.
- Config: typed configuration from JSON, files, pairs, and environment variables.
- OpenAPI: route metadata, schemas, and generated documents.
- Observability: additive production setup for HTTP metrics, traces, events, jobs, lifecycle validation, and official adapter operations.
- Dashboard: optional protected
/nidus/dashboardruntime cockpit with Home, Atlas, Routes, Timeline, Adapters, Settings, JSON APIs, route snapshots, timeline storage, and SSE stream. - Events and jobs: in-process event buses, sync/async queues, and observed runners.
- Testing:
nidus_testing::TestAppfor in-memory request tests and provider overrides.
Production Defaults
nidus-http provides opt-in production API defaults for request IDs, request context, health, readiness checks, metrics, CORS, body limits, timeout responses, security headers, structured logging, error envelopes, unmatched-route not_found fallbacks, and OpenTelemetry trace-context helpers. The defaults return normal Axum routers and Tower layers, so applications can replace or reorder the boundary.
Recommended production observability is additive:
use *;
let observability = production
.version
.environment
.prometheus
.tracing
.otel_from_env;
let app =
.with_observability
.build
.await?;
Automatic instrumentation applies where Nidus owns the integration point:
HTTP middleware, ObservedEventBus, ObservedJobRunner, module validation, and
official adapter builders. Raw SQLx queries, raw cache clients, ORMs, queues,
and HTTP clients remain explicit application instrumentation.
Adapter Story
The nidus facade stays lean. Redis and SQLx data access, Kafka,
NATS/JetStream, RabbitMQ, SQS, SQLx-backed durable jobs, OpenTelemetry, and
Sentry live in separately installable crates. Each adapter exposes the native
ecosystem client and composes with typed DI, lifecycle, health, observability,
and dashboard events. Shared envelopes and correlation live in
nidus-integrations; broker-specific semantics are not hidden behind a generic
queue API. Delivery is documented as at-most-once or at-least-once where
appropriate, never as universal exactly-once processing.
Examples
examples/hello-world: minimal server.examples/openapi: OpenAPI JSON and docs routes.examples/production-api: production middleware defaults.examples/dashboard-api: embedded dashboard runtime cockpit with bearer or local-disabled auth, SQLite storage, metadata-only capture, route snapshots, Atlas graph, Timeline event/job filters, APIs, SSE, and live curl checks.examples/realworld-api: team tasks API with modules, SQLite, validation, OpenAPI, health, observability, request IDs, guards, CORS, limits, timeouts, events, and jobs.examples/sqlx-appandexamples/cache-app: official adapter wiring.examples/integrations-production: runnable Redis, MySQL, CockroachDB, Kafka, NATS/JetStream, RabbitMQ, SQS, durable jobs, OpenTelemetry, and Sentry entrypoints.examples/external-support-desk: copyable external-user support desk API using crates.io-style dependencies, DI, ticket lifecycle routes, API-key auth, request IDs, validation errors, not-found behavior, andnidus-testing.examples/external-commerce: copyable external-user commerce API using crates.io-style dependencies,nidus-sqlxSQLite wiring,nidus-cache, products, carts, inventory, idempotent checkout, health/readiness, metrics, andnidus-testing.
Run an example:
The external-* examples are standalone Cargo packages with their own
[workspace] tables. Verify them from their folders or with
bash scripts/verify-external-examples.sh; they intentionally do not use local
workspace path dependencies. Before 1.0.10 is published to crates.io, verify
the same examples against temporary local patches:
NIDUS_EXTERNAL_EXAMPLES_LOCAL_PATCH=1
That mode copies the external examples to a temp directory and appends
temporary [patch.crates-io] entries there only. The checked-in examples stay
copyable crates.io-style manifests.
Documentation
- Local Markdown docs: docs/
- Generated website source: website/
- GitHub Pages build:
.github/workflows/pages.yml
Build and check the static website locally:
Release Status
Nidus 1.0.0 established the public crate set. The current release track is 1.0.10, adding separately installable data, messaging, durable-job, OpenTelemetry, and Sentry integrations while preserving the facade and existing 1.x APIs.
Fuzzing
The fuzz/ package uses cargo-fuzz to compile deterministic fuzz targets for
config parsing, route path normalization, and OpenAPI path normalization:
Use short local runs for development and CI compile checks for release hygiene.
Contributing
Read CONTRIBUTING.md. Changes should be small, tested, documented, and aligned with Rust ecosystem expectations.
License
Licensed under either MIT or Apache-2.0.