project-structure · codewithmukesh — Claude Code skill for .NET solution layout
A skill that tells your agent how to lay out a .NET solution: central package versions, shared build properties, .slnx format and naming rules.
npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a claude-codeWhat project-structure does
The skill spells out how a .NET solution is organised: where source and test projects live, how projects and namespaces are named, which files control the build. Your agent reads those rules and places new code accordingly instead of guessing.
Inside are four principles plus file examples. Directory.Packages.props keeps NuGet versions in one place, so individual .csproj files carry no Version attribute. Directory.Build.props holds shared settings such as the target framework, Nullable and ImplicitUsings. The solution uses the .slnx format, source sits in src/, tests in tests/.
There is a naming table (solution, project, namespace, feature folder) and a walk through anti-patterns: versions scattered across projects, build properties repeated in every .csproj, test projects mixed into src/. The package versions in the examples are marked as illustrative, and the author advises resolving current ones with dotnet add package without the --version flag. The skill installs into Claude, Codex, Cursor, GitHub Copilot, Gemini CLI and OpenCode, so the layout stays the same whichever editor you switch to.
What it helps with
- lay out a new .NET project across src and tests folders
- pull NuGet versions into one file instead of a dozen .csproj files
- move shared build settings into Directory.Build.props
- migrate a solution from .sln to .slnx
- pick names for projects, namespaces and feature folders
Example prompts for the agent
- Scaffold a new .NET project using the project-structure skill conventions
- Move the package versions into Directory.Packages.props
- Check the solution layout — test projects belong in tests/, not src/
How to install project-structure
1Skills CLI (Vercel)
npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a claude-code2Manually: put the files in place
~/.claude/skills/project-structure/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/project-structure/
1Skills CLI (Vercel)
npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a codex2Manually: put the files in place
.agents/skills/project-structure/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a cursor2Manually: put the files in place
.cursor/skills/project-structure/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install codewithmukesh/dotnet-claude-kit project-structure2Manually: put the files in place
.github/skills/project-structure/SKILL.md1Skills CLI (Vercel)
npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a gemini-cli2Platform CLI
gemini skills install https://github.com/codewithmukesh/dotnet-claude-kit --path skills/project-structureManually: put the files in place
.devin/skills/project-structure/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about project-structure
How do I install project-structure in Claude?
Run npx skills add codewithmukesh/dotnet-claude-kit --skill project-structure -a claude-code. The skill lands in ~/.claude/skills/project-structure/SKILL.md.
What does the project-structure skill do?
It documents .NET solution conventions: the .slnx format, central package management, shared build properties, global usings and naming rules. The agent applies them when you set up a solution or add a project.
Does this skill require .NET 10?
The Directory.Build.props example uses net10.0 and LangVersion 14, and global.json pins SDK 10.0.100. Those are example values, not a hard requirement — swap in your own target framework.
Source text
SKILL.md · MIT
---
name: project-structure
description: >
.NET solution and project structure conventions. Covers .slnx format,
Directory.Build.props, Directory.Packages.props for central package management,
global usings, and naming conventions.
Load this skill when setting up a new solution, adding projects, configuring
build properties, or when the user mentions "solution structure", ".slnx",
"Directory.Build.props", "central package management", "Directory.Packages.props",
"global usings", ".editorconfig", "project layout", or "naming conventions".
---
# Project Structure
## Core Principles
1. **Central package management** — Use `Directory.Packages.props` to manage NuGet package versions in one place. No version numbers in individual `.csproj` files.
2. **Shared build properties** — Use `Directory.Build.props` for common settings (target framework, nullable, implicit usings). Don't repeat in every project.
3. **.slnx for solutions** — The new XML-based solution format is cleaner and more merge-friendly than the legacy `.sln` format.
4. **src/tests separation** — Source projects in `src/`, test projects in `tests/`. Clear boundary.
## Patterns
### Solution Layout
```
MyApp/
├── MyApp.slnx # Solution file
├── Directory.Build.props # Shared MSBuild properties
├── Directory.Packages.props # Central package management
├── .editorconfig # Code style rules
├── .gitignore
├── global.json # SDK version pinning
├── src/
│ ├── MyApp.Api/ # Web API (entry point)
│ │ ├── MyApp.Api.csproj
│ │ ├── Program.cs
│ │ └── Features/
│ ├── MyApp.Domain/ # Domain entities, value objects (optional)
│ │ └── MyApp.Domain.csproj
│ └── MyApp.Infrastructure/ # EF Core, external services (optional)
│ └── MyApp.Infrastructure.csproj
└── tests/
└── MyApp.Api.Tests/
└── MyApp.Api.Tests.csproj
```
### Directory.Build.props
```xml
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>14</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
</Project>
```
### Directory.Packages.props (Central Package Management)
```xml
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<!-- Versions below are illustrative — resolve the current stable versions
with `dotnet add package <name>` (no --version flag); see the packages rule -->
<!-- ASP.NET Core -->
<PackageVersion Include="Mediator.Abstractions" Version="3.0.0" />
<PackageVersion Include="Mediator.SourceGenerator" Version="3.0.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<!-- Data -->
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.10" />
<!-- Observability -->
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
<!-- Testing -->
<PackageVersion Include="xunit.v3" Version="3.2.2" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.10" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.13.0" />
</ItemGroup>
</Project>
```
### Project File (.csproj) with Central Package Management
```xml
<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- No TargetFramework here — inherited from Directory.Build.props -->
<ItemGroup>
<!-- No Version attribute — managed centrally -->
<PackageReference Include="Mediator.Abstractions" />
<PackageReference Include="Mediator.SourceGenerator" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="Serilog.AspNetCore" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyApp.Domain\MyApp.Domain.csproj" />
<ProjectReference Include="..\MyApp.Infrastructure\MyApp.Infrastructure.csproj" />
</ItemGroup>
</Project>
```
### global.json (SDK Pinning)
```json
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
```
### .slnx Solution Format
```xml
<Solution>
<Folder Name="/src/">
<Project Path="src/MyApp.Api/MyApp.Api.csproj" />
<Project Path="src/MyApp.Domain/MyApp.Domain.csproj" />
<Project Path="src/MyApp.Infrastructure/MyApp.Infrastructure.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MyApp.Api.Tests/MyApp.Api.Tests.csproj" />
</Folder>
</Solution>
```
### Naming Conventions
| Element | Convention | Example |
|---------|-----------|---------|
| Solution | `CompanyName.AppName` or `AppName` | `MyApp.slnx` |
| Project | `AppName.Layer` | `MyApp.Api`, `MyApp.Domain` |
| Namespace | Matches folder path | `MyApp.Api.Features.Orders` |
| Feature folder | PascalCase, plural | `Features/Orders/` |
| Test project | `ProjectName.Tests` | `MyApp.Api.Tests` |
## Anti-patterns
### Don't Scatter Package Versions
```xml
<!-- BAD — version in every .csproj, version drift -->
<PackageReference Include="Mediator.Abstractions" Version="2.0.0" /> <!-- in Project A -->
<PackageReference Include="Mediator.Abstractions" Version="3.0.0" /> <!-- in Project B -->
<!-- GOOD — central management, one version -->
<!-- Directory.Packages.props: <PackageVersion Include="Mediator.Abstractions" Version="3.0.0" /> -->
<!-- .csproj: <PackageReference Include="Mediator.Abstractions" /> -->
```
### Don't Repeat Build Properties
```xml
<!-- BAD — same properties in every .csproj -->
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<!-- GOOD — once in Directory.Build.props, inherited everywhere -->
```
### Don't Mix Source and Test Projects
```
# BAD — tests mixed with source
src/
MyApp.Api/
MyApp.Api.Tests/ # test project in src/
# GOOD — clear separation
src/
MyApp.Api/
tests/
MyApp.Api.Tests/
```
## Decision Guide
| Scenario | Recommendation |
|----------|---------------|
| New solution | `.slnx` format |
| Package version management | `Directory.Packages.props` (central) |
| Shared build settings | `Directory.Build.props` |
| SDK version pinning | `global.json` |
| Common using directives | Global usings in `Directory.Build.props` |
| Small API (1-2 devs) | Single project (`MyApp.Api`) |
| Medium API (3-5 devs) | 2-3 projects (`Api`, `Domain`, `Infrastructure`) |
| Large / modular app | Module-per-project with shared `Contracts` |
© codewithmukesh · MIT · codewithmukesh/dotnet-claude-kit
Similar skills
Everything for Backend and APIs →project-structure by other authors comes first.