███╗ ██╗███████╗███████╗████████╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗
████╗ ██║██╔════╝██╔════╝╚══██╔══╝██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
██╔██╗ ██║█████╗ ███████╗ ██║ █████╗ ██║ ██║██████╔╝██║ ███╗█████╗
██║╚██╗██║██╔══╝ ╚════██║ ██║ ██╔══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝
██║ ╚████║███████╗███████║ ██║ ██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗
╚═╝ ╚═══╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
NestForge is a high-performance backend framework designed for developers who crave the modularity and Dependency Injection (DI) of NestJS but want the memory safety and blazing speed of the Rust ecosystem.
Important
Stable Release NestForge 1.2.0 is now published on crates.io.
- Module system with
importsandexports - Dependency Injection with simple provider registration
- Controller macros (
#[controller],#[routes],#[get],#[post],#[put],#[delete]) - Request extractors (
Inject<T>,Param<T>,Body<T>,ValidatedBody<T>) - Extended request extractors (
Query<T>,Headers,Cookies,RequestId) - Built-in HTTP error type (
HttpException) - Guard and interceptor pipeline (global + route-level)
- Route-targeted middleware consumer API on the HTTP factory
- Auth primitives (
AuthUser,OptionalAuthUser,BearerToken, auth resolvers, auth guards) - Route versioning (
#[nestforge::version("1")]) - Global prefix support (
.with_global_prefix("api")) - Generated OpenAPI docs from controller metadata with runtime mounting helpers
- Optional GraphQL support through a dedicated
nestforge-graphqlcrate and factory helpers - Optional gRPC transport support through a dedicated
nestforge-grpccrate - Optional WebSocket gateway support through a dedicated
nestforge-websocketscrate - Optional scheduler support through a dedicated
nestforge-schedulecrate - Config module with env loading and schema validation
- Data layer crates (
nestforge-db,nestforge-orm,nestforge-data) - Testing helpers with module overrides plus HTTP and GraphQL test routers
- CLI for scaffolding, generators, DB migrations, docs skeleton, formatting
crates/nestforge: public crate users importcrates/nestforge-core: DI, module graph, route builder, validation, resource servicecrates/nestforge-http: app bootstrap factorycrates/nestforge-macros: framework macroscrates/nestforge-cli:nestforgeCLI binarycrates/nestforge-config: env/config loading and validationcrates/nestforge-db: DB wrapper and migrations supportcrates/nestforge-orm: relational ORM abstraction layercrates/nestforge-data: non-relational data abstractionsexamples/hello-nestforge: full example appexamples/hello-nestforge-graphql: GraphQL-first example appexamples/hello-nestforge-grpc: gRPC-first example appexamples/hello-nestforge-microservices: microservice registry + in-process client example appexamples/hello-nestforge-websockets: WebSocket-first example app
git clone https://github.com/vernonthedev/nestforge.git
cd nestforge
cargo check --workspace
cargo run -p hello-nestforgeGraphQL-first example:
cargo run -p hello-nestforge-graphqlgRPC-first example:
cargo run -p hello-nestforge-grpcWebSocket-first example:
cargo run -p hello-nestforge-websocketsMicroservices-first example:
cargo run -p hello-nestforge-microservicesServer runs on:
http://127.0.0.1:3000
NestForge now uses a Rust-native direct release flow driven by the repository release script.
- Pushes to
mainrun the repository release script directly. - Conventional commits since the last version tag determine the next semver bump automatically.
- Changed crates are versioned, tagged, released on GitHub, and published to crates.io in dependency order.
- The primary published changelog is updated at
crates/nestforge/CHANGELOG.md, so conventional commits remain the source for changelog entries.
Repository setup required for publishing:
- Add
CARGO_REGISTRY_TOKENto GitHub Actions secrets. - Keep using Conventional Commits for changes you want included in the release notes.
- Expect first-time publishes for brand new crates to require a manual bootstrap publish before full automation can take over.
Install locally from this workspace:
cargo install --path crates/nestforge-cliCreate an app:
nestforge new demo-api
cd demo-api
cargo runCreate a GraphQL-first app:
nestforge new demo-graphql --transport graphqlCreate a gRPC-first app:
nestforge new demo-grpc --transport grpcCreate a microservices-first app:
nestforge new demo-bus --transport microservicesCreate a WebSocket-first app:
nestforge new demo-events --transport websocketsGenerate code:
nestforge g module users
nestforge g resource users --module users
nestforge g guard auth
nestforge g filter rewrite_bad_request
nestforge g middleware audit
nestforge g interceptor logging
nestforge g graphql users
nestforge g grpc billing
nestforge g gateway eventsDB commands:
nestforge db init
nestforge db generate create_users_table
nestforge db migrate
nestforge db statusUtilities:
nestforge docs
nestforge fmtuse nestforge::NestForgeFactory;
NestForgeFactory::<AppModule>::create()?
.with_global_prefix("api")
.with_openapi_docs("My API", "1.0.0")?
.use_guard::<AllowAllGuard>()
.use_interceptor::<LoggingInterceptor>()
.listen(3000)
.await?;examples/hello-nestforge demonstrates:
- Root controllers (
AppController,HealthController) at app root - Feature modules (
users,settings,versioning) in Nest-style folders - CRUD controllers + services with
ResourceService<T> - Validation via
ValidatedBody<T> - Guard/interceptor usage at route level
- Generated
/docsand/openapi.jsonroutes from controller metadata - Config loading with
ConfigModule::for_root - Versioned routes (
v1,v2)
Enable the graphql feature and merge a GraphQL schema directly into the app:
use nestforge::{
async_graphql::{EmptyMutation, EmptySubscription, Object, Schema},
NestForgeFactory, NestForgeFactoryGraphQlExt,
};
struct QueryRoot;
#[Object]
impl QueryRoot {
async fn health(&self) -> &str {
"ok"
}
}
let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish();
NestForgeFactory::<AppModule>::create()?
.with_graphql(schema)
.listen(3000)
.await?;Enable the grpc feature and bootstrap a gRPC transport with the dedicated factory:
use nestforge::NestForgeGrpcFactory;
NestForgeGrpcFactory::<AppModule>::create()?
.with_addr("127.0.0.1:50051")
.listen_with(|ctx, addr| async move {
tonic::transport::Server::builder()
// .add_service(MyGeneratedServer::new(MyGrpcService::new(ctx)))
.serve(addr)
.await
})
.await?;See examples/hello-nestforge-grpc for a full tonic-based setup with proto/greeter.proto,
build.rs, generated bindings, and provider resolution through GrpcContext.
Enable the websockets feature and mount a gateway directly into the HTTP app:
use nestforge::{
Message, NestForgeFactory, NestForgeFactoryWebSocketExt, WebSocket, WebSocketContext,
WebSocketGateway,
};
struct EventsGateway;
impl WebSocketGateway for EventsGateway {
fn on_connect(
&self,
_ctx: WebSocketContext,
mut socket: WebSocket,
) -> core::pin::Pin<Box<dyn core::future::Future<Output = ()> + Send>> {
Box::pin(async move {
let _ = socket.send(Message::Text("connected".into())).await;
})
}
}
NestForgeFactory::<AppModule>::create()?
.with_websocket_gateway(EventsGateway)
.listen(3000)
.await?;- Main Documentation: https://nestforge.suredoc.net
- Wiki: https://github.com/vernonthedev/nestforge/wiki
- Project docs: https://vernonthedev.github.io/nestforge/docs/Home.md
See CONTRIBUTING.md.
Apache-2.0 (LICENSE).