DotnetForge 2.7.0

dotnet tool install --global DotnetForge --version 2.7.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local DotnetForge --version 2.7.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=DotnetForge&version=2.7.0
                    
nuke :add-package DotnetForge --version 2.7.0
                    

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

# 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
cd MyApp
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)

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

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 an Azure App Registration:

  1. Create App Registration in Azure Portal → Microsoft Entra ID → App registrations
  2. Add App Roles (e.g., admin, author, reader) under App roles → Create app role
  3. Configure API Permissions → Expose an API → Add a scope (e.g., api://<client-id>/access_as_user)
  4. For the React frontend (forge-fullstack): Create a second App Registration (SPA type) with redirect URI http://localhost:5173
  5. Update appsettings.json with your Tenant ID, Client ID, and Domain

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
  }
}

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
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
2.7.0 5 3/6/2026
2.6.2 29 3/5/2026
2.6.1 30 3/5/2026
2.6.0 40 3/5/2026
2.5.1 36 3/5/2026
2.5.0 38 3/5/2026
2.3.1 44 3/3/2026
2.3.0 40 3/3/2026