pub const CARGO: &str = r#"[package]
name = "{{kebab}}"
version = "0.1.0"
edition = "2024"
rust-version = "1.95"
# Own workspace root — scaffold works even inside another repo's tree.
[workspace]
[dependencies]
anyhow = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
nest-rs-core = "{{nestrs_version}}"
nest-rs-config = "{{nestrs_version}}"
nest-rs-guards = "{{nestrs_version}}"
nest-rs-http = "{{nestrs_version}}"
nest-rs-interceptors = "{{nestrs_version}}"
nest-rs-opentelemetry = { version = "{{nestrs_version}}", features = ["http"] }
poem = { version = "3", features = ["tower-compat", "anyhow", "rustls"] }
[dev-dependencies]
nest-rs-testing = { version = "{{nestrs_version}}", features = ["opentelemetry"] }
"#;
pub const MAIN: &str = r#"use anyhow::Result;
use nest_rs_config::Environment;
use nest_rs_core::App;
use nest_rs_opentelemetry::OpenTelemetry;
use {{snake}}::{{module}};
#[tokio::main]
async fn main() -> Result<()> {
let _environment = Environment::init();
let _telemetry = OpenTelemetry::init("{{kebab}}")?;
App::builder()
.module::<{{module}}>()
.build()
.await?
.run()
.await
}
"#;
pub const LIB_HELLO: &str = r#"mod controller;
mod module;
mod service;
pub use module::{{module}};
"#;
pub const LIB_EMPTY: &str = r#"mod module;
pub use module::{{module}};
"#;
pub const MODULE_HELLO: &str = r#"use nest_rs_core::module;
use nest_rs_http::HttpModule;
use nest_rs_opentelemetry::OpenTelemetryModule;
use crate::controller::{{controller}};
use crate::service::{{service}};
#[module(
imports = [
OpenTelemetryModule,
HttpModule::for_root(None),
],
providers = [{{service}}, {{controller}}],
)]
pub struct {{module}};
"#;
pub const MODULE_EMPTY: &str = r#"use nest_rs_core::module;
use nest_rs_http::HttpModule;
use nest_rs_opentelemetry::OpenTelemetryModule;
#[module(imports = [
OpenTelemetryModule,
HttpModule::for_root(None),
])]
pub struct {{module}};
"#;
pub const SERVICE: &str = r#"use nest_rs_core::injectable;
#[injectable]
#[derive(Default)]
pub struct {{service}};
impl {{service}} {
pub fn greeting(&self) -> String {
"Hello World".to_string()
}
}
"#;
pub const CONTROLLER: &str = r#"use std::sync::Arc;
use nest_rs_http::{controller, routes};
use crate::service::{{service}};
#[controller(path = "/")]
pub struct {{controller}} {
#[inject]
svc: Arc<{{service}}>,
}
#[routes]
impl {{controller}} {
#[get("/")]
async fn hello(&self) -> String {
self.svc.greeting()
}
}
"#;
pub const E2E: &str = r#"use {{snake}}::{{module}};
use nest_rs_testing::TestApp;
#[tokio::test]
async fn hello_endpoint_greets() {
let app = TestApp::builder()
.with_test_telemetry()
.module::<{{module}}>()
.build()
.await
.expect("{{module}} boots and mounts its routes");
let resp = app.http().get("/").send().await;
resp.assert_status_is_ok();
resp.assert_text("Hello World").await;
}
"#;
pub const DOCKERFILE: &str = r#"# syntax=docker/dockerfile:1.7
#
# Build: docker build -t {{kebab}} .
# Run: docker run --rm -p 3000:3000 {{kebab}}
#
# Multi-stage: compile in Rust slim, run on distroless nonroot.
ARG RUST_VERSION=1.95
FROM rust:${RUST_VERSION}-slim-trixie AS builder
WORKDIR /app
COPY Cargo.toml ./
COPY src ./src
RUN cargo build --release
FROM gcr.io/distroless/cc-debian13:nonroot AS runtime
COPY --from=builder /app/target/release/{{kebab}} /usr/local/bin/app
EXPOSE 3000
USER nonroot:nonroot
ENTRYPOINT ["/usr/local/bin/app"]
"#;
pub const JUSTFILE: &str = r#"_default:
@just --list
# Run the app with auto-reload — watches the source, rebuilds and restarts on
# save (loads `.env` / `.env.development` from the project root).
dev:
bacon run-long
# Run an optimized build.
start:
cargo run --release
# Build the release binary (target/release/{{kebab}}).
build:
cargo build --release
# Type-check without codegen.
check:
cargo check
# Tests — unit/integration/e2e/doctests. Usage: nestrs run test [unit|e2e|doc]
mod test
# Database lifecycle. Usage: nestrs run db up|down|fresh|status|seed|reset
mod db
# Apply rustfmt.
fmt:
cargo fmt
# Clippy (strict) + format check.
lint:
cargo clippy -- -D warnings
cargo fmt --check
"#;
pub const TEST_JUSTFILE: &str = r#"# Test recipes, exposed as `nestrs run test <kind>` (see `mod test` in the
# Justfile). Bare `nestrs run test` lists these — pick a kind to run.
# Bare `nestrs run test` lists the kinds instead of running one.
_default:
@just --list test
# Unit + integration + doctests, no DB.
unit:
cargo nextest run -E 'not binary(e2e)'
cargo test --doc # nextest skips doctests; run them too
# e2e tests — your `tests/e2e.rs` bucket (boots the real app).
e2e:
cargo nextest run -E 'binary(e2e)'
# Doctests only — the code examples inside `///` doc comments.
doc:
cargo test --doc
"#;
pub const README: &str = r#"# {{kebab}}
**Standalone** NestRS app — one crate, logic in `src/`. `GET /`, HTTP only,
no auth, no database. Generated by `nestrs new {{kebab}}`.
## Run
```bash
nestrs run dev
nestrs run build # → target/release/{{kebab}}
nestrs run start # build + run in release
```
Open **http://localhost:3000/** in your browser — you should see `Hello World`.
Need several apps sharing product code? Scaffold a
[workspace](/cli/#layout-detection) instead:
`nestrs new <name>`.
## Configuration
Environment variables load from the [`.env` cascade`](https://nestrs.dev/configuration/).
Committed defaults live in `.env` and `.env.development`; copy `.env.example`
to `.env.local` when you add Postgres or Redis later.
"#;