DotnetForge.Templates 2.17.0

dotnet new install DotnetForge.Templates::2.17.0
                    
This package contains a .NET Template Package you can call from the shell/command line.

DotnetForge

Production-ready .NET 10 project templates. One NuGet package, three templates.

Quick Start

# Install the CLI tool (recommended)
dotnet tool install -g DotnetForge

# Interactive wizard — prompts for everything
dotnet forge new

# Browser-based UI — visual form with all options
dotnet forge new --ui

# Specify your app name, prompts for remaining options
dotnet forge new MyApp

# Fully non-interactive
dotnet forge new MyApp --template forge-aspire --auth keycloak --include-react-email

# Build and run (auto-detects AppHost or API project)
cd MyApp
dotnet forge watch

# Or run explicitly
dotnet run --project src/MyApp.AppHost

The CLI auto-installs DotnetForge.Templates on first run if missing. To update:

dotnet tool update -g DotnetForge

Templates

Template Command What you get
Forge API dotnet forge new MyApp -t forge-api Standalone Minimal API with OpenTelemetry, health checks, resilience
Forge Aspire dotnet forge new MyApp -t forge-aspire API + .NET Aspire orchestration + Azure deployment
Forge Full-Stack dotnet forge new MyApp -t forge-fullstack API + Aspire + React frontend (Vite/Bun) + Docker deployment
Forge Email (item) dotnet new forge-email -n PasswordReset Scaffold a new email action + model + React Email template

CLI Flags

Flag Default Description
[name] (prompted) Project name (PascalCase). Auto-generates lowercase variants for config.
-t, --template (prompted) Template short name: forge-api, forge-aspire, forge-fullstack
-o, --output current dir Output directory
--auth-provider / --auth (prompted) Identity provider: keycloak or entra
--entra-tenant-id common Microsoft Entra ID tenant ID (only when --auth entra)
--entra-client-id YOUR_CLIENT_ID Microsoft Entra ID application (client) ID (only when --auth entra)
--entra-domain yourtenant.onmicrosoft.com Microsoft Entra ID tenant domain (only when --auth entra)
--include-react-email false Include React Email template system (Bun + MailKit + Scriban)
--ui false Open browser-based project configuration form

When a flag is omitted, the CLI prompts interactively. In non-interactive terminals (CI/pipes), template and name are required.

Browser UI (--ui)

Run dotnet forge new --ui to open a browser-based project configuration wizard instead of terminal prompts. The wizard walks you through five steps: Template → Platform → Project Details → Configure → Review & Create.

Features

  • Multi-step wizard with animated transitions between steps
  • Dark / Light / System themes — defaults to dark mode with a warm industrial-forge aesthetic. Light mode uses a warm parchment palette. Toggle with the theme button in the header or Ctrl+D.
  • Platform-independent auth — choosing a platform (Self-Hosted, Azure) sets a sensible default auth provider, but you can switch between Keycloak and Entra ID on the Configure step regardless of platform
  • Conditional sections — AppHost storage and Docker options appear only when the selected template supports them
  • Real-time validation — PascalCase project name enforcement with live preview of generated project names

Keyboard Shortcuts

The entire wizard is fully keyboard-navigable — no mouse required.

Key Action
Navigate between cards and options
Enter / Space Select focused item
Tab / Shift+Tab Move between form fields
15 Jump directly to a wizard step
Esc Go back to previous step
Ctrl+D Toggle theme (Dark → Light → System)
? Show keyboard shortcuts overlay

Development (UI only)

For hot-reload UI development:

# Terminal 1: Start the API server
dotnet run --project src/DotnetForge.Cli/ -- new --ui

# Terminal 2: Start Vite dev server with HMR
cd src/DotnetForge.Cli/ui && npm run dev
# Open http://localhost:5299

To skip the UI build during C#-only development, pass -p:BuildUi=false to dotnet build.

Watch Command

Auto-detect and run a project with dotnet watch:

# Auto-detect project type (Aspire AppHost → API fallback)
dotnet forge watch

# Search a specific directory
dotnet forge watch ./src

# Explicit project path (skip detection)
dotnet forge watch --project src/MyApp.AppHost/MyApp.AppHost.csproj

# Force target type
dotnet forge watch --target aspire
dotnet forge watch --target api
Flag Description
[directory] Directory to search (defaults to current directory)
-p, --project Explicit .csproj path (skips auto-detection)
-t, --target Force target type: aspire or api

Detection priority: Aspire AppHost projects are detected first (by IsAspireHost, Aspire.Hosting, or Aspire.AppHost.Sdk markers in .csproj). If none found, falls back to API projects matching *.Api.csproj. When multiple projects are found, an interactive prompt lets you pick one.

Manual Install (without CLI)

You can also install templates directly and use dotnet new:

dotnet new install DotnetForge.Templates

dotnet new forge-aspire -n MyApp
dotnet new forge-aspire -n MyApp --auth-provider entra
dotnet new forge-api -n MyApp --auth entra --entra-tenant-id abc123 --entra-client-id def456

# Add a new email action to an existing project
dotnet new forge-email -n PasswordReset

What's Included

API (forge-api / forge-aspire / forge-fullstack)

  • .NET 10 Minimal APIs with feature-slice architecture
  • Keycloak or Microsoft Entra ID authentication + role-based authorization
  • PostgreSQL with EF Core, migrations, Ulid primary keys
  • FusionCache L1 memory + L2 Redis with backplane
  • JSON:API compliant responses via JsonApiKit (cursor + offset pagination)
  • MediaKit file storage (Local, S3, SeaweedFS, RustFS, Azure Blob/Azurite) with image conversions
  • Scalar API docs with OAuth2 Authorization Code flow
  • Rate limiting (Global, PublicRead, Authenticated, AdminWrite policies)
  • FluentValidation + ErrorOr result pattern
  • Domain events via EF Core interceptors
  • xUnit v3 unit tests + k6 performance tests
  • ArchUnitNET architecture tests (dependency direction, naming, endpoint conventions)

Aspire Orchestration (forge-aspire / forge-fullstack)

  • PostgreSQL, Redis containers with data volumes (Keycloak container when using Keycloak auth)
  • DbGate web-based database management (persistent, for Postgres and Redis)
  • Configurable storage — S3-compatible (RustFS, SeaweedFS) or Azure Blob (Azurite emulator)
  • Enterprise publisher for deployment documentation
  • Aspire Dashboard with seed data command
  • Azure Container Apps deployment via azd up
  • Feature/integration tests with Aspire.Hosting.Testing

React Frontend (forge-fullstack only)

  • React 19 + TypeScript + Vite + Bun (auto-installed via WithBunPackageInstallation())
  • TanStack Router + Query
  • Radix UI + Tailwind CSS 4
  • oidc-spa OIDC integration (Keycloak or Entra ID)
  • i18n via i18next
  • Orval API client generation from OpenAPI
  • Docker multi-stage build with nginx

Setting up Microsoft Entra ID

When using --auth-provider entra, you need Azure App Registration(s).

API App Registration

  1. Create App Registration in Azure Portal > Microsoft Entra ID > App registrations
    • Platform type: Web (no redirect URI needed for the API)
    • Under Authentication > Implicit grant: leave both checkboxes unchecked (uses PKCE)
  2. Expose an API > Add a scope:
    • Application ID URI: api://<client-id> (auto-generated)
    • Scope name: access_as_user
    • Who can consent: Admins and users
  3. App Roles > Create app role:
    • Display name: Admin, Value: admin, Allowed member types: Users/Groups
    • Repeat for other roles as needed (author, reader)
  4. Assign roles to users: Go to Enterprise Applications > your app > Users and groups > Add user/group > select role
  5. Update appsettings.json with your Tenant ID, Client ID, and Domain

SPA App Registration (forge-fullstack only)

  1. Create a second App Registration for the Web app:
    • Platform type: Single-page application (SPA)
    • Redirect URIs: http://localhost:5173 (add production URL later)
    • Implicit grant: leave both checkboxes unchecked (uses PKCE)
  2. API Permissions on the SPA app:
    • Add a permission > My APIs > select the API app > Delegated permissions > select access_as_user
  3. Update .env with SPA Client ID, API Client ID, and Authority URL

The Entra parameters are optional at project creation — you can leave the defaults and configure appsettings.json later:

# Minimal — configure in appsettings.json after project creation
dotnet new forge-api -n MyApp --auth entra

# Or provide values upfront
dotnet new forge-api -n MyApp --auth entra \
  --entra-tenant-id your-tenant-id \
  --entra-client-id your-client-id \
  --entra-domain yourtenant.onmicrosoft.com

Architecture

MyApp/
├── src/
│   ├── MyApp.Api/                  # Minimal API
│   │   ├── Data/                   # Repositories + cached decorators
│   │   ├── Entities/               # Domain entities (Book, Author, Category)
│   │   ├── Features/               # Feature slices (Admin, Public, Dev)
│   │   ├── Infrastructure/         # Auth, caching, validation, etc.
│   │   ├── Migrations/             # EF Core migrations
│   │   └── Services/               # Cross-cutting services
│   ├── MyApp.AppHost/              # Aspire orchestrator (aspire/fullstack)
│   ├── MyApp.AppHost.Extensions/   # Enterprise publisher
│   ├── MyApp.ServiceDefaults/      # Shared OTel + health + resilience
│   ├── MyApp.Web/                  # React frontend (fullstack)
│   └── MyApp.KeycloakTheme/        # Keycloakify theme (fullstack, Keycloak only)
├── tests/
│   ├── MyApp.Api.ArchitectureTests/ # ArchUnitNET architecture rules
│   ├── MyApp.Api.UnitTests/        # xUnit v3 + NSubstitute
│   ├── MyApp.Api.FeatureTests/     # Aspire integration tests (aspire/fullstack)
│   └── MyApp.PerformanceTests/     # k6 load tests
├── MyApp.slnx                      # Solution file
├── docker-compose.api.yml          # Production API deployment
└── docker-compose.api.build.yml    # Local API build

Architecture Tests

Every scaffolded project includes automated architecture tests powered by ArchUnitNET that enforce the feature-slice conventions and prevent architectural drift.

Enforced Rules

Endpoint Conventions (EndpointArchitectureTests)

  • IEndpoint implementations must reside in the Features namespace
  • Endpoint classes must not be abstract
  • Endpoint classes must be sealed

Dependency Direction (DependencyArchitectureTests)

  • Entities must not depend on Features, Infrastructure, or Data
  • Infrastructure must not depend on Features
  • Data must not depend on Features
  • No cross-feature slice dependencies (e.g., Features.Admin.Books must not reference Features.Admin.Authors)

Naming Conventions (NamingConventionTests)

  • Interfaces start with I
  • Validators end with Validator and reside in Features
  • Repository interfaces reside in Data
  • Cached decorators reside in Data.Cached
  • Entity classes in Entities inherit from BaseEntity
  • No public fields in entities

Configuration

Rules are enabled by default. To disable enforcement (tests skip instead of fail), edit tests/MyApp.Api.ArchitectureTests/appsettings.Testing.json:

{
  "ArchitectureTests": {
    "EnforceRules": false
  }
}

Alternatively, override via environment variable (useful in CI):

ArchitectureTests__EnforceRules=false dotnet test

When disabled, all tests are skipped during dotnet test but remain available for manual verification.

Deployment Options

Azure (Aspire + Full-Stack)

azd init
azd up

Docker Compose (all templates)

docker compose -f docker-compose.api.build.yml up -d

GitHub Actions

  • deploy-azure.yml — Azure Container Apps via azd (aspire/fullstack)
  • deploy-docker.yml — Multi-arch Docker build + webhook deploy (fullstack)

Sample Domain

The template includes a Books Management sample domain with:

  • Book — title, ISBN, description, cover image, gallery
  • Author — name, biography, avatar
  • Category — name, description, icon

This gives you working CRUD endpoints, relationships, media uploads, caching, and search — all wired up and ready to extend. See SAMPLE_DOMAIN.md for details.

Development (Template Authors)

Repository Structure

dotnet-forge/
├── shared/           # Common files across all templates (edit here)
├── overrides/        # Template-specific file variants (edit here)
│   ├── forge-api/
│   ├── forge-aspire/
│   └── forge-fullstack/
├── template-configs/ # .template.config per template
├── templates/        # BUILD OUTPUT (git-ignored)
├── src/
│   └── DotnetForge.Cli/  # Interactive CLI tool (dotnet forge)
├── build.ps1         # Assembles templates from shared + overrides
└── DotnetForge.Templates.csproj

Build & Test

# Assemble templates
./build.ps1

# Install locally
dotnet new install ./templates/forge-api
dotnet new install ./templates/forge-aspire
dotnet new install ./templates/forge-fullstack

# Test
dotnet new forge-aspire -n TestApp
cd TestApp && dotnet build

# Package
dotnet pack DotnetForge.Templates.csproj

# Build CLI tool
dotnet build src/DotnetForge.Cli/
dotnet pack src/DotnetForge.Cli/DotnetForge.Cli.csproj --output ./artifacts
dotnet tool install --global --add-source ./artifacts DotnetForge

Uninstall

# CLI tool
dotnet tool uninstall -g DotnetForge

# Templates only
dotnet new uninstall DotnetForge.Templates
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.17.0 188 3/23/2026
2.15.0 188 3/16/2026
2.10.2 187 3/12/2026
2.10.0 187 3/12/2026
2.9.0 184 3/12/2026
2.7.1 183 3/7/2026
2.7.0 188 3/6/2026
2.6.2 178 3/5/2026
2.6.1 180 3/5/2026
2.6.0 184 3/5/2026
2.5.1 180 3/5/2026
2.1.0 193 3/3/2026
2.0.4 184 3/3/2026
2.0.3 188 3/2/2026
1.2.0 199 3/2/2026
1.1.0 211 3/1/2026
1.0.0 194 2/28/2026