
MSBuild Item Management
FreeStreamline your MSBuild item group management.
Free · Opens the source repo
What MSBuild Item Management does
The MSBuild Item Management skill provides a comprehensive guide to managing item groups within MSBuild projects, specifically focusing on the operations of Include, Remove, and Update. These operations are essential for adding new items, excluding files, and modifying existing item metadata without re-adding them. This skill is particularly useful for developers working with .csproj files who need to ensure their item management practices are efficient and correct.
With this skill, users can learn how to effectively utilize batching with metadata, which allows for optimized execution based on unique metadata values. The skill includes practical examples of item transformations and conditional item inclusion, helping developers to manage their project files more effectively. By understanding these patterns, users can avoid common pitfalls such as cross-product batching and ensure that their build processes are streamlined and error-free.
This skill is designed for developers who are looking to diagnose and fix item group anti-patterns in their MSBuild projects. It will help in addressing issues like duplicate file warnings caused by SDK globbing, ensuring that targets do not run more times than expected, and managing generated files correctly to avoid cluttering the source directory. By following the guidelines provided, developers can enhance their understanding of MSBuild item management and improve their project's build performance.
When to use it
Use this skill when you need to diagnose issues in your MSBuild item groups or when you're reviewing item management practices in .csproj files.
When not to use it
This skill is not suitable for general anti-patterns unrelated to item management or for non-MSBuild build systems.
What you can build with it
Fixing Duplicate File Warnings
Use this skill to address CS2002 warnings caused by duplicate files in your MSBuild project.
Optimizing Build Performance
Implement the provided patterns to streamline your build process and avoid unnecessary target executions.
Reviewing Item Management Practices
Utilize this skill to audit your .csproj files for correct item management and adherence to best practices.
How to install MSBuild Item Management
View source1. Install with the skills CLI
npx skills add dotnet/skills/item-management --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by dotnetMSBuild Item Management Patterns
Canonical patterns for working with item groups, from Microsoft.Common.CurrentVersion.targets.
Include / Remove / Update — Three Operations
| Operation | Purpose | When to use |
|---|---|---|
Include | Add new items to the group | Creating items with identity + metadata |
Remove | Remove items matching a pattern | Excluding files or clearing a group |
Update | Modify metadata on existing items | Adding/changing metadata without re-adding |
Include — Add Items
<ItemGroup>
<Compile Include="Generated\*.cs">
<AutoGen>true</AutoGen>
</Compile>
</ItemGroup>
Remove — Subtract Items
<ItemGroup>
<!-- Remove specific items -->
<Reference Remove="$(AdditionalExplicitAssemblyReferences)" />
<!-- Set subtraction: prior minus current -->
<_CleanOrphanFileWrites Include="@(_CleanPriorFileWrites)"
Exclude="@(_CleanCurrentFileWrites)" />
<!-- Clear an entire group -->
<_Temporary Remove="@(_Temporary)" />
</ItemGroup>
Update — Modify Existing Items
<ItemGroup>
<EmbeddedResource Update="@(EmbeddedResource)"
Condition="'%(NuGetPackageId)' == 'Microsoft.CodeAnalysis.Collections'">
<GenerateSource>true</GenerateSource>
<ClassName>Microsoft.CodeAnalysis.Collections.SR</ClassName>
</EmbeddedResource>
</ItemGroup>
Update does not add items — it only modifies items already in the group.
Item Batching — %(Metadata)
When %(Metadata) appears in target attributes or task parameters, MSBuild batches execution per unique metadata value.
Target-level batching (Outputs)
<Target Name="GenerateSatelliteAssemblies"
Inputs="$(MSBuildAllProjects);@(_SatelliteAssemblyResourceInputs)"
Outputs="$(IntermediateOutputPath)%(Culture)\$(TargetName).resources.dll">
<!-- Runs once per unique Culture value -->
</Target>
Task-level batching
<Copy SourceFiles="@(_SourceItems)"
DestinationFiles="@(_SourceItems->'$(OutDir)%(TargetPath)')">
</Copy>
Per-item filtering with Condition
<ItemGroup>
<_ResxOutput Include="@(EmbeddedResource->'%(OutputResource)')"
Condition="'%(EmbeddedResource.WithCulture)' == 'false'" />
</ItemGroup>
Batching rules
%(Metadata)inConditionorOutputs→ target batches per unique value.%(Metadata)in task parameters → task batches per unique value.- Do not mix
%()from different item groups in the same expression — this causes a cross-product (see Common Pitfalls).
Item Transforms — @(Item->'expression')
Transforms create new item lists by applying an expression to each item:
<!-- Transform file paths to destinations -->
<Copy SourceFiles="@(IntermediateAssembly)"
DestinationFiles="@(IntermediateAssembly->'$(OutDir)%(Filename)%(Extension)')"/>
<!-- Transform with separator for display -->
<Message Text="Files: @(Compile->'%(Filename)', ', ')" />
Exclude Pattern — Set Subtraction on Include
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Generated\**;Tests\**" />
</ItemGroup>
Exclude only works on Include — it cannot be used with Update or Remove.
Conditional Item Inclusion
<!-- Condition on ItemGroup — all or nothing -->
<ItemGroup Condition="'$(NetCoreBuild)' == 'true'">
<PackageReference Include="System.IO.Pipelines" />
</ItemGroup>
<!-- Condition on individual items -->
<ItemGroup>
<PackageReference Include="System.IO.Pipelines"
Condition="'$(NetCoreBuild)' == 'true'" />
</ItemGroup>
PrivateAssets on Tool/Analyzer Packages
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="all" />
</ItemGroup>
Common Pitfalls
Cross-product batching
Referencing %(Metadata) from two different item groups creates O(N×M) executions:
<!-- BAD: Cross-product of @(Source) × @(Config) -->
<Exec Command="process %(Source.Identity) with %(Config.Identity)" />
<!-- GOOD: Reference one group via batching, the other via property -->
<Exec Command="process %(Source.Identity) with $(ConfigFile)" />
Generated files in source tree
Write to $(IntermediateOutputPath) (obj/), not the source directory. Source-tree generation pollutes version control and can cause duplicate compilation via globs.
Missing FileWrites
Every file created during a target must be added to @(FileWrites) for dotnet clean support.
Frequently asked questions about MSBuild Item Management
Similar skills
Python PyPI Package Builder
Streamline the process of creating and publishing Python packages.
Minecraft Plugin Development
Streamline your Minecraft server plugin creation.
MCP Server Builder
Easily build .NET MCP servers with the latest standards.
CommunityToolkit.Mvvm Messenger
Decoupled communication for ViewModels in .NET applications.
MVVM Toolkit DI
Streamline ViewModel integration with Dependency Injection in .NET.
MCP Apps Builder
Essential guidelines for MCP server development.
