Custom templates for dotnet new

The .NET SDK comes with many templates already installed and ready for you to use. The dotnet new command isn't only the way to use a template, but also how to install and uninstall templates. You can create your own custom templates for any type of project, such as an app, service, tool, or class library. You can even create a template that outputs one or more independent files, such as a configuration file.

You can install custom templates from a NuGet package on any NuGet feed, by referencing a NuGet .nupkg file directly, or by specifying a file system directory that contains the template. The template engine offers features that allow you to replace values, include and exclude files, and execute custom processing operations when your template is used.

The template engine is open source, and the online code repository is at dotnet/templating on GitHub. More templates, including templates from third parties, can be found using dotnet new search. For more information about creating and using custom templates, see How to create your own templates for dotnet new and the dotnet/templating GitHub repo Wiki.

Note

Template examples are available at the dotnet/templating GitHub repository.

To follow a walkthrough and create a template, see the Create a custom template for dotnet new tutorial.

.NET default templates

When you install the .NET SDK, you receive over a dozen built-in templates for creating projects and files, including console apps, class libraries, unit test projects, ASP.NET Core apps (including Angular and React projects), and configuration files. To list the built-in templates, run the dotnet new list command:

dotnet new list

Configuration

A template is composed of the following parts:

  • Source files and folders.
  • A configuration file (template.json).

Source files and folders

The source files and folders include whatever files and folders you want the template engine to use when the dotnet new <TEMPLATE> command is run. The template engine is designed to use runnable projects as source code to produce projects. This has several benefits:

  • The template engine doesn't require you to inject special tokens into your project's source code.
  • The code files aren't special files or modified in any way to work with the template engine. So, the tools you normally use when working with projects also work with template content.
  • You build, run, and debug your template projects just like you do for any of your other projects.
  • You can quickly create a template from an existing project just by adding a ./.template.config/template.json configuration file to the project.

Files and folders stored in the template aren't limited to formal .NET project types. Source files and folders may consist of any content that you wish to create when the template is used, even if the template engine produces just one file as its output.

Files generated by the template can be modified based on logic and settings you've provided in the template.json configuration file. The user can override these settings by passing options to the dotnet new <TEMPLATE> command. A common example of custom logic is providing a name for a class or variable in the code file that's deployed by a template.

template.json

The template.json file is placed in a .template.config folder in the root directory of the template. The file provides configuration information to the template engine. The minimum configuration requires the members shown in the following table, which is sufficient to create a functional template.

Member Type Description
$schema URI The JSON schema for the template.json file. Editors that support JSON schemas enable JSON-editing features when the schema is specified. For example, Visual Studio Code requires this member to enable IntelliSense. Use a value of http://json.schemastore.org/template.
author string The author of the template.
classifications array(string) Zero or more characteristics of the template that a user might use to find the template when searching for it. The classifications also appear in the Tags column when it appears in a list of templates produced by using the dotnet new list command.
identity string A unique name for this template.
name string The name for the template that users should see.
shortName string A default shorthand name for selecting the template that applies to environments where the template name is specified by the user, not selected via a GUI. For example, the short name is useful when using templates from a command prompt with CLI commands.
sourceName string The name in the source tree to replace with the name the user specifies. The template engine will look for any occurrence of the sourceName mentioned in the config file and replace it in file names and file contents. The value to be replaced with can be given using the -n or --name options while running a template. If no name is specified, the current directory is used.
preferNameDirectory Boolean Indicates whether to create a directory for the template if name is specified but an output directory isn't set (instead of creating the content directly in the current directory). The default value is false.

The full schema for the template.json file is found at the JSON Schema Store. For more information about the template.json file, see the dotnet templating wiki. For deeper examples and information on how to make your templates visible in Visual Studio, check out the resources that Sayed Hashimi has created.

Example

For example, here's a template folder that contains two content files: console.cs and readme.txt. There's also the required folder named .template.config that contains the template.json file.

└───mytemplate
    │   console.cs
    │   readme.txt
    │
    └───.template.config
            template.json

The template.json file looks like the following:

{
  "$schema": "http://json.schemastore.org/template",
  "author": "Travis Chau",
  "classifications": [ "Common", "Console" ],
  "identity": "AdatumCorporation.ConsoleTemplate.CSharp",
  "name": "Adatum Corporation Console Application",
  "shortName": "adatumconsole"
}

The mytemplate folder is an installable template package. Once the package is installed, the shortName can be used with the dotnet new command. For example, dotnet new adatumconsole would output the console.cs and readme.txt files to the current folder.

Template localization

The .NET templates are localizable. If a template is localized for the language matching the current locale, its elements appear in the same language as the CLI. Localization is optional when creating new templates.

The localizable elements on a template are:

  • Name
  • Author
  • Description
  • Symbols
    • Description
    • Display Name
    • Descriptions and Display name of choices for choice parameters
  • Post actions
    • Description
    • Manual instructions

Localization files have a JSON format, and just one file per culture should exist. The naming convention is: templatestrings.<lang code>.json, where lang code corresponds to one of the CultureInfo options. All localization files should be inside the .template-config\localize folder.

The localization JSON consists of key value pairs:

  • The key is the reference to an element of template.json to be localized. If the element is a child, use the full path with a / delimiter.
  • The value is the localization string of the element given by the key.

For more information about localizing templates, see the dotnet templating wiki's localization page.

Example

For example, here's template.json file with some localizable fields:

{
  "$schema": "http://json.schemastore.org/template",
  "author": "Microsoft",
  "classifications": "Config",
  "name": "EditorConfig file",
  "description": "Creates an .editorconfig file for configuring code style preferences.",
  "symbols": {
    "Empty": {
      "type": "parameter",
      "datatype": "bool",
      "defaultValue": "false",
      "displayName": "Empty",
      "description": "Creates empty .editorconfig instead of the defaults for .NET."
    }
  }
}

And some fields are to be localized to Brazilian Portuguese. The filename will be templatestrings.pt-BR.json to match the culture, and it would look like:

{
  "author": "Microsoft",
  "name": "Arquivo EditorConfig",
  "description": "Cria um arquivo .editorconfig para configurar as preferências de estilo de código.",
  "symbols/Empty/displayName": "Vazio",
  "symbols/Empty/description": "Cria .editorconfig vazio em vez dos padrões para .NET."
}

Pack a template into a NuGet package (nupkg file)

A custom template is packed with the dotnet pack command and a .csproj file. Alternatively, NuGet can be used with the nuget pack command along with a .nuspec file. However, NuGet requires the .NET Framework on Windows and Mono on Linux and macOS.

The .csproj file is slightly different from a traditional code-project .csproj file. Note the following settings:

  1. The <PackageType> setting is added and set to Template.
  2. The <PackageVersion> setting is added and set to a valid NuGet version number.
  3. The <PackageId> setting is added and set to a unique identifier. This identifier is used to uninstall the template pack and is used by NuGet feeds to register your template pack.
  4. Generic metadata settings should be set: <Title>, <Authors>, <Description>, and <PackageTags>.
  5. The <TargetFramework> setting must be set, even though the binary produced by the template process isn't used. In the example below it's set to netstandard2.0.

A template package, in the form of a .nupkg NuGet package, requires that all templates be stored in the content folder within the package. There are a few more settings to add to a .csproj file to ensure that the generated .nupkg can be installed as a template pack:

  1. The <IncludeContentInPack> setting is set to true to include any file the project sets as content in the NuGet package.
  2. The <IncludeBuildOutput> setting is set to false to exclude all binaries generated by the compiler from the NuGet package.
  3. The <ContentTargetFolders> setting is set to content. This makes sure that the files set as content are stored in the content folder in the NuGet package. This folder in the NuGet package is parsed by the dotnet template system.

An easy way to exclude all code files from being compiled by your template project is by using the <Compile Remove="**\*" /> item in your project file, inside an <ItemGroup> element.

An easy way to structure your template pack is to put all templates in individual folders, and then each template folder inside of a templates folder that is located in the same directory as your .csproj file. This way, you can use a single project item to include all files and folders in the templates as content. Inside of an <ItemGroup> element, create a <Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" /> item.

Here's an example .csproj file that follows all of these guidelines. It packs the templates child folder to the content package folder and excludes any code file from being compiled.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <PackageType>Template</PackageType>
    <PackageVersion>1.0</PackageVersion>
    <PackageId>AdatumCorporation.Utility.Templates</PackageId>
    <Title>AdatumCorporation Templates</Title>
    <Authors>Me</Authors>
    <Description>Templates to use when creating an application for Adatum Corporation.</Description>
    <PackageTags>dotnet-new;templates;contoso</PackageTags>
    <TargetFramework>netstandard2.0</TargetFramework>

    <IncludeContentInPack>true</IncludeContentInPack>
    <IncludeBuildOutput>false</IncludeBuildOutput>
    <ContentTargetFolders>content</ContentTargetFolders>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
    <Compile Remove="**\*" />
  </ItemGroup>

</Project>

The following example demonstrates the file and folder structure of using a .csproj to create a template package. The MyDotnetTemplates.csproj file and templates folder are both located at the root of a directory named project_folder. The templates folder contains two templates, mytemplate1 and mytemplate2. Each template has content files and a .template.config folder with a template.json config file.

project_folder
│   MyDotnetTemplates.csproj
│
└───templates
    ├───mytemplate1
    │   │   console.cs
    │   │   readme.txt
    │   │
    │   └───.template.config
    │           template.json
    │
    └───mytemplate2
        │   otherfile.cs
        │
        └───.template.config
                template.json

Note

To ensure that the template package appears in dotnet new search result, set the NuGet package type to Template.

Install a template package

Use the dotnet new install command to install a template package.

To install a template package from a NuGet package stored at nuget.org

Use the NuGet package identifier to install a template package.

dotnet new install <NUGET_PACKAGE_ID>

To install a template package from a custom NuGet source

Provide a custom NuGet source (for example, https://api.my-custom-nuget.com/v3/index.json).

dotnet new install <NUGET_PACKAGE_ID> --nuget-source <SOURCE>

To install a template package from a local nupkg file

Provide the path to a .nupkg NuGet package file.

dotnet new install <PATH_TO_NUPKG_FILE>

To install a template package from a file system directory

Templates can be installed from a template folder, such as the mytemplate1 folder from the previous example. Specify the folder path of the .template.config folder. The path to the template directory doesn't need to be absolute.

dotnet new install <FILE_SYSTEM_DIRECTORY>

Get a list of installed template packages

The uninstall command, without any other parameters, lists all installed template packages and included templates.

dotnet new uninstall

That command returns something similar to the following output:

Currently installed items:
   Microsoft.Azure.WebJobs.ProjectTemplates
      Version: 4.0.1942
      Details:
         Author: Microsoft
         NuGetSource: https://api.nuget.org/v3/index.json
      Templates:
         Azure Functions (func) C#
         Azure Functions (func) F#
      Uninstall Command:
         dotnet new uninstall Microsoft.Azure.WebJobs.ProjectTemplates
...

The first level of items after Currently installed items: are the identifiers used in uninstalling a template package. And in the previous example, Microsoft.Azure.WebJobs.ProjectTemplates is listed. If the template package was installed by using a file system path, this identifier is the folder path of the .template.config folder. Only the template packages installed via dotnet new install are shown in the list. The template packages that are built into the .NET SDK aren't shown.

Uninstall a template package

Use the dotnet new uninstall command to uninstall a template package.

If the package was installed by either a NuGet feed or by a .nupkg file directly, provide the identifier.

dotnet new uninstall <NUGET_PACKAGE_ID>

If the package was installed by specifying a path to the .template.config folder, use that path to uninstall the package. You can see the absolute path of the template package in the output provided by the dotnet new uninstall command. For more information, see the Get a list of installed templates section.

dotnet new uninstall <FILE_SYSTEM_DIRECTORY>

Create a project using a custom template

After a template is installed, use the template by executing the dotnet new <TEMPLATE> command as you would with any other preinstalled template. You can also specify options to the dotnet new command, including template-specific options you configured in the template settings. Supply the template's short name directly to the command:

dotnet new <TEMPLATE>

See also