Step-by-Step Guide to Building Custom .NET Templates
Introduction
The .NET SDK provides a powerful templating engine that allows developers to create reusable templates for projects, files, and solution structures. This guide covers how to create, package, and distribute custom templates using the dotnet new command-line interface.
Understanding .NET Templates
Templates in .NET are packages that contain source files and a configuration that determines how those files should be transformed when instantiated. They provide a way to standardize project structures, apply consistent patterns, and save time when creating new applications or components.
Key Concepts
Template: A set of files and folders that can be transformed into a working project or component
Template Package: A NuGet package containing one or more templates
Template Engine: The system that processes templates and generates output
Template Structure
A basic template consists of:
Source Files and Folders: The content that will be used to generate new projects
Configuration Files: JSON files that control how the template behaves
The .template.config Directory
Every template must have a .template.config directory at its root containing at least a template.json file. This file provides metadata and configuration for the template.
template.json
The template.json file defines how the template works. Here's a breakdown of the essential fields:
{
"$schema": "http://json.schemastore.org/template",
"author": "Your Name",
"classifications": ["Category1", "Category2"],
"identity": "Your.Template.Identity",
"name": "User-friendly Template Name",
"shortName": "template-shortname",
"sourceName": "TemplateSourceName",
"preferNameDirectory": true,
"tags": {
"language": "C#",
"type": "project"
}
}
$schema: Reference to the JSON schema
author: Creator of the template
classifications: Categories for organizing templates
identity: Unique identifier for the template
name: Display name for the template
shortName: Command-line alias for the template
sourceName: The name in source files to be replaced with the user's specified name
preferNameDirectory: Whether to create a directory for the output
tags: Metadata for filtering templates
Advanced Template Configuration
Parameters and Symbols
Templates can define parameters that users can specify when creating a new instance:
"symbols": {
"ParameterName": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"description": "Parameter description"
}
}
Conditional Content
You can include or exclude files based on parameter values:
"sources": [
{
"modifiers": [
{
"condition": "(!ParameterName)",
"exclude": ["ExcludedFolder/**/*"]
}
]
}
]
Post-Creation Actions
You can define actions to be executed after the template is instantiated:
"postActions": [
{
"description": "Additional setup steps",
"manualInstructions": [
{
"text": "Instructions for the user after template creation"
}
],
"actionId": "CB9A6CF3-4F5C-4860-B9D2-03A574959774",
"continueOnError": true
}
]
Packaging and Distribution
Creating a NuGet Package
To distribute your template, you need to create a NuGet package:
- Create a
.csprojfile to define the package:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageType>Template</PackageType>
<PackageVersion>1.0.0</PackageVersion>
<PackageId>Your.Template.Package</PackageId>
<Title>Your Template Package</Title>
<Authors>Your Name</Authors>
<Description>Your template description</Description>
<PackageTags>dotnet-new;templates;yourKeywords</PackageTags>
<TargetFramework>netstandard2.0</TargetFramework>
<IncludeContentInPack>true</IncludeContentInPack>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>content</ContentTargetFolders>
<NoWarn>$(NoWarn);NU5128</NoWarn>
<NoDefaultExcludes>true</NoDefaultExcludes>
</PropertyGroup>
<ItemGroup>
<Content Include="content/**/*" Exclude="content/**/bin/**;content/**/obj/**" />
<Compile Remove="**/*" />
</ItemGroup>
</Project>
- Organize your files:
YourTemplatePackage/
├── YourTemplatePackage.csproj
└── content/
├── .template.config/
│ └── template.json
└── YourTemplateFiles/
- Build the package:
dotnet pack -c Release
Installing Templates
Templates can be installed from various sources:
- From a NuGet package:
dotnet new install Your.Template.Package
- From a local .nupkg file:
dotnet new install path/to/Your.Template.Package.1.0.0.nupkg
- From a file system directory:
dotnet new install path/to/template/directory
Using Templates
Once installed, you can use your template with:
dotnet new template-shortname -n ProjectName [--parameter1 value1]
Template Localization
Templates can be localized to display in different languages. Create a localize folder in the .template.config directory with JSON files named according to the language code:
.template.config/
├── template.json
└── localize/
├── templatestrings.en-US.json
└── templatestrings.es-ES.json
Each localization file contains key-value pairs matching the fields in template.json that should be translated.
Visual Studio Integration
To make your template appear in Visual Studio's "New Project" dialog:
- Add Visual Studio metadata to the
template.json:
"tags": {
"language": "C#",
"type": "project",
"vs-workload": "dotnetcore"
}
- For complete integration, consider creating a Visual Studio Extension (VSIX) package.
Best Practices
Clear naming: Choose descriptive, specific names for your templates
Good documentation: Include clear descriptions and examples
Minimal dependencies: Avoid unnecessary dependencies
Thoughtful defaults: Provide sensible default values for parameters
Testing: Test your templates in various environments before distribution
Versioning: Follow semantic versioning for your template packages
Organization: Keep templates focused and organized by functionality
Troubleshooting
Common Issues
Template Not Found: Ensure the template is installed correctly
File Not Included: Check your include/exclude patterns
Parameter Not Working: Verify parameter configuration in
template.jsonTemplate Not Visible in VS: Check Visual Studio integration settings
Debugging
For detailed logs when using templates:
dotnet new template-shortname -n ProjectName --verbosity diagnostic
Conclusion
Custom .NET templates are a powerful way to standardize code structures, enforce architectural patterns, and improve productivity. By following this guide, you can create, package, and distribute templates that will help your team or the wider .NET community build better software more efficiently.

