Skip to content

Quick Start

Build your first NestForge application from scratch in minutes.

This guide will walk you through creating a “Hello World” application using the NestForge CLI. You’ll learn how to set up the project, define a controller, and run the server.

  1. Create the Project

    Use the CLI to scaffold a new project. We’ll call it hello-nestforge.

    Terminal window
    nestforge new hello-nestforge
    cd hello-nestforge
  2. Examine the Structure

    The CLI generates the app bootstrap files at the root of src/. The key files are:

    • src/main.rs: Entry point that bootstraps the application.
    • src/app_module.rs: Root module that wires up controllers and providers.
    • src/app_controller.rs: Starter HTTP controller.
    • src/app_service.rs: A simple service used by the starter controller.
    • src/health_controller.rs: A health check endpoint.
  3. Define a Controller

    Open src/app_controller.rs. By default, the CLI creates a simple controller for you. Let’s look at how that controller is defined:

    use nestforge::{controller, routes, HttpException, Inject};
    use crate::app_service::AppService;
    #[controller("")]
    pub struct AppController;
    #[routes]
    impl AppController {
    #[nestforge::get("/")]
    async fn root(service: Inject<AppService>) -> Result<String, HttpException> {
    Ok(service.welcome_message())
    }
    }
  4. Register the Controller and Service

    In src/app_module.rs, the generated AppModule registers the starter controllers and the AppService provider:

    use nestforge::{module, ConfigModule, ConfigOptions, Provider};
    use crate::{
    app_config::AppConfig,
    app_controller::AppController,
    app_service::AppService,
    health_controller::HealthController,
    };
    fn load_app_config() -> anyhow::Result<AppConfig> {
    Ok(ConfigModule::for_root::<AppConfig>(ConfigOptions::new().env_file(".env"))?)
    }
    #[module(
    controllers = [AppController, HealthController],
    providers = [
    load_app_config()?,
    Provider::factory(|container| {
    let config = container.resolve::<AppConfig>()?;
    Ok(AppService::new(config.as_ref()))
    }),
    ],
    )]
    pub struct AppModule;
  5. Bootstrap the App

    The src/main.rs file bootstraps the application using NestForgeFactory. The current CLI scaffold also adds a global prefix and API version:

    use nestforge::NestForgeFactory;
    use crate::app_module::AppModule;
    async fn bootstrap() -> anyhow::Result<()> {
    NestForgeFactory::<AppModule>::create()?
    .with_global_prefix("api")
    .with_version("v1")
    .listen(3000)
    .await
    }
    #[tokio::main]
    async fn main() -> anyhow::Result<()> {
    bootstrap().await
    }
  6. Run it!

    Start your server with Cargo:

    Terminal window
    cargo run

    Visit http://localhost:3000/api/v1 in your browser. You should see a welcome message from the generated AppService.

  • #[controller]: Defines a base path for all routes within the struct.
  • #[routes]: A required attribute for the impl block where your handlers live.
  • Inject<T>: Resolves a provider from the application container.
  • NestForgeFactory: The engine that resolves your module graph and mounts the Axum router.
  • .with_global_prefix("api") and .with_version("v1"): Add the application prefix and version segment used by generated routes.