Template Authoring

Guides creation and validation of custom dotnet new templates. Generates templates from existing projects and validates template.json for authoring issues. USE FOR: creating a reusable dotnet new template from an existing project, validating template.json files for schema compliance and parameter issues, bootstrapping .template.config/template.json with correct identity, shortName, parameters, and post-actions, packaging templates as NuGet packages for distribution. DO NOT USE FOR: finding or using existing templates (use template-discovery and template-instantiation), MSBuild project file issues unrelated to template authoring, NuGet package publishing (only template packaging structure).

Workflow

Step 1: Bootstrap from existing project

Analyze the source .csproj and create a .template.config/template.json:

  1. Create .template.config directory next to the project
  2. Generate template.json with identity (reverse-DNS), name, shortName, sourceName (project name for replacement), classifications, and tags
  3. Preserve from source — generic dotnet new templates frequently get these wrong, so verify each is carried over from the original .csproj:

1. SDK typeMicrosoft.NET.Sdk, Microsoft.NET.Sdk.Web, Microsoft.NET.Sdk.Worker, etc. 2. Analyzer/package reference metadataPrivateAssets, IncludeAssets, ExcludeAssets 3. `OutputType` and other key propertiesTreatWarningsAsErrors, Nullable, LangVersion 4. CPM participation — no inline Version attributes when a Directory.Packages.props is present 5. Custom build props/targets and Directory.Build.props conventions 6. Repo conventions — folder layout, naming, global.json SDK pin

Minimal example:

{
  "$schema": "http://json.schemastore.org/template",
  "author": "MyOrg",
  "classifications": ["Library"],
  "identity": "MyOrg.Templates.MyLib",
  "name": "My Library Template",
  "shortName": "mylib",
  "sourceName": "MyLib",
  "tags": { "language": "C#", "type": "project" }
}

Step 2: Validate template.json

Validate the generated template.json using the template-validation skill (it owns the full rule set — required fields, identity format, reserved shortName conflicts, parameter datatypes, post-actions, constraints, and tags).

Quick summary of what gets checked:

  • Required fieldsidentity, name, and shortName must be present.
  • ShortName conflicts — avoid names that collide with dotnet new subcommands. Read the authoritative set from the Commands: section of dotnet new --help for the installed SDK and do not hardcode it (it can change between versions); illustrative examples from current SDKs are install, uninstall, update, list, search, details, create. A conflict happens because dotnet new <name> would be parsed as the subcommand of the same name. Top-level dotnet verbs like build, run, test, and publish do NOT conflict. Run dotnet new list to confirm the name is not already taken.
  • Parameters, post-actions, tags — see template-validation for the complete rules, including the valid datatype list.

Step 3: Refine the template

Based on validation results and user requirements:

  1. Add parameters with appropriate types (string, bool, choice), defaults, and descriptions
  2. Add conditional content using #if preprocessor directives for optional features
  3. Configure post-actions for solution add, restore, or custom scripts
  4. Set constraints to restrict which SDKs or workloads the template supports
  5. Add classifications and tags for discoverability

Step 4: Test the template locally

dotnet new install ./path/to/template/root
dotnet new mylib --name TestProject --dry-run
dotnet new mylib --name TestProject --output ./test-output
dotnet build ./test-output/TestProject

Related skills

Compares two or more dotnet new templates side by side to help users choose between them based on parameters, feature support, frameworks, and classifications.