Skills template-authoring

install
source · Clone the upstream repo
git clone https://github.com/dotnet/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dotnet/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/dotnet-template-engine/skills/template-authoring" ~/.claude/skills/dotnet-skills-template-authoring && rm -rf "$T"
manifest: plugins/dotnet-template-engine/skills/template-authoring/SKILL.md
source content

Template Authoring

This skill helps an agent create and validate custom

dotnet new
templates. It guides bootstrapping templates from existing projects and validates
template.json
files for authoring issues before publishing.

When to Use

  • User wants to create a reusable template from an existing .csproj
  • User wants to validate a template.json for correctness
  • User is setting up
    .template.config/template.json
    from scratch
  • User wants to package a template for NuGet distribution

When Not to Use

  • User wants to find or use existing templates — route to
    template-discovery
    or
    template-instantiation
  • User has MSBuild issues unrelated to template authoring — route to
    dotnet-msbuild
    plugin

Inputs

InputRequiredDescription
Source project pathFor creationPath to the .csproj to use as template source
template.json pathFor validationPath to an existing template.json to validate
Template nameFor creationHuman-readable name for the template
Short nameRecommendedShort name for
dotnet new <shortname>
usage

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: SDK type, package references with metadata (PrivateAssets, IncludeAssets), properties (OutputType, TreatWarningsAsErrors), CPM patterns

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

Read and review the

template.json
for common authoring issues:

Validation checks to perform:

  • Required fields — verify
    identity
    ,
    name
    , and
    shortName
    are present
  • Identity format — use reverse-DNS format (e.g.,
    MyOrg.Templates.WebApi
    )
  • Parameter issues — check datatypes are valid (
    string
    ,
    bool
    ,
    choice
    ,
    int
    ,
    float
    ), choices have defaults, descriptions are present
  • ShortName conflicts — avoid names that collide with built-in CLI commands (
    build
    ,
    run
    ,
    test
    ,
    publish
    ). Check with
    dotnet new list
    to see if the name is already taken
  • Post-action completeness — verify post-actions have all required configuration
  • Tags — ensure language, type, and classification tags are set for discoverability

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

Validation

  • template.json
    passes manual validation with zero errors
  • Template identity and shortName are unique and meaningful
  • All parameters have descriptions and appropriate defaults
  • Template can be installed, dry-run, and instantiated successfully
  • Created projects build cleanly with
    dotnet build
  • Conditional content produces correct output for all parameter combinations

Common Pitfalls

PitfallSolution
Identity format issuesUse reverse-DNS format (e.g.,
MyOrg.Templates.WebApi
). Avoid spaces or special characters.
ShortName conflicts with CLI commandsAvoid names like
build
,
run
,
test
,
publish
. Check by running
dotnet new list
to see if the name is already taken.
Missing parameter descriptionsEvery parameter should have a
description
and
displayName
for discoverability.
Not testing all parameter combinationsUse
dotnet new <template> --dry-run
with different parameter values to verify conditional content works correctly.
Hardcoded versions in templateUse
sourceName
replacement for project names and consider parameterizing framework versions.
Not setting classificationsAdd appropriate
classifications
(e.g.,
["Web", "API"]
) for template discovery.

More Info