Managing NuGet package versions can become difficult when a solution contains multiple projects. If every project specifies its own package versions, keeping those versions synchronized can quickly become a maintenance problem.

Central Package Management (CPM) provides a way to manage NuGet package versions from a central location instead of repeating package versions across every project.

In this guide, you'll learn what Central Package Management is, how to enable it, how to define package versions centrally, and how to use it in a multi-project .NET solution.


๐Ÿ“ฆ What Is Central Package Management?

Central Package Management allows you to define NuGet package versions in a central MSBuild file called:

Directory.Packages.props

Instead of defining the version separately in every project's .csproj file, the package version can be defined once.

For example, without Central Package Management, you might have:

<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />

If several projects use the same package, the version may be repeated throughout the solution.

With Central Package Management, the version can be moved to Directory.Packages.props.


๐Ÿ—๏ธ Why Use Central Package Management?

Imagine a solution containing several projects:

MySolution
โ”‚
โ”œโ”€โ”€ MyApp.Web
โ”œโ”€โ”€ MyApp.API
โ”œโ”€โ”€ MyApp.Services
โ”œโ”€โ”€ MyApp.Data
โ””โ”€โ”€ MyApp.Tests

Suppose all five projects use the same NuGet package.

Without centralized version management, you may have to maintain the package version in several project files.

This can lead to situations where one project uses:

PackageX 5.0.0

while another project uses:

PackageX 4.8.0

Central Package Management helps keep package versions consistent across the solution.


๐Ÿ“ Where Should Directory.Packages.props Go?

Create Directory.Packages.props in the directory that contains your solution or project structure.

For example:

MySolution/
โ”‚
โ”œโ”€โ”€ Directory.Packages.props
โ”œโ”€โ”€ MySolution.sln
โ”‚
โ”œโ”€โ”€ MyApp.Web/
โ”‚   โ””โ”€โ”€ MyApp.Web.csproj
โ”‚
โ”œโ”€โ”€ MyApp.API/
โ”‚   โ””โ”€โ”€ MyApp.API.csproj
โ”‚
โ”œโ”€โ”€ MyApp.Data/
โ”‚   โ””โ”€โ”€ MyApp.Data.csproj
โ”‚
โ””โ”€โ”€ MyApp.Tests/
    โ””โ”€โ”€ MyApp.Tests.csproj

The central package file can then apply to projects underneath that directory.


โš™๏ธ Step 1: Create Directory.Packages.props

Create a new file named:

Directory.Packages.props

A basic example looks like this:

<Project>

  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>

</Project>

The ManagePackageVersionsCentrally property enables Central Package Management.


๐Ÿ“Œ Step 2: Add Central Package Versions

Once Central Package Management is enabled, package versions can be defined using PackageVersion.

<Project>

  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>

  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json"
                    Version="13.0.3" />

    <PackageVersion Include="Serilog"
                    Version="4.0.0" />
  </ItemGroup>

</Project>

Now the package versions are managed centrally.


๐Ÿงฉ Step 3: Remove Versions from .csproj Files

With Central Package Management enabled, your project files can reference packages without specifying their versions.

For example:

<ItemGroup>

    <PackageReference Include="Newtonsoft.Json" />

    <PackageReference Include="Serilog" />

</ItemGroup>

The versions are obtained from Directory.Packages.props.

This gives you a much cleaner separation between:


๐Ÿ” Before and After

โŒ Without Central Package Management

<ItemGroup>

    <PackageReference Include="Newtonsoft.Json"
                      Version="13.0.3" />

    <PackageReference Include="Serilog"
                      Version="4.0.0" />

</ItemGroup>

โœ… With Central Package Management

In Directory.Packages.props:

<ItemGroup>

    <PackageVersion Include="Newtonsoft.Json"
                    Version="13.0.3" />

    <PackageVersion Include="Serilog"
                    Version="4.0.0" />

</ItemGroup>

And in the project:

<ItemGroup>

    <PackageReference Include="Newtonsoft.Json" />

    <PackageReference Include="Serilog" />

</ItemGroup>

๐ŸŒณ Central Package Management in a Multi-Project Solution

Central Package Management becomes especially useful when several projects share the same dependencies.

MySolution
โ”‚
โ”œโ”€โ”€ Directory.Packages.props
โ”‚
โ”œโ”€โ”€ Web
โ”‚   โ””โ”€โ”€ Web.csproj
โ”‚
โ”œโ”€โ”€ API
โ”‚   โ””โ”€โ”€ API.csproj
โ”‚
โ”œโ”€โ”€ Services
โ”‚   โ””โ”€โ”€ Services.csproj
โ”‚
โ””โ”€โ”€ Data
    โ””โ”€โ”€ Data.csproj

The central file might contain:

<Project>

  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>

  <ItemGroup>

    <PackageVersion Include="Microsoft.Extensions.Logging"
                    Version="9.0.0" />

    <PackageVersion Include="Newtonsoft.Json"
                    Version="13.0.3" />

    <PackageVersion Include="Serilog"
                    Version="4.0.0" />

  </ItemGroup>

</Project>

Each project can then reference only the packages it actually needs.


๐ŸŽฏ Central Versions vs Project Dependencies

One important advantage of Central Package Management is that package ownership becomes clearer.

The project file answers:

Which packages does this project use?

The central file answers:

Which versions of those packages should the solution use?

This makes dependency management easier to review and maintain.


โš ๏ธ What About Packages That Need Different Versions?

Central Package Management does not necessarily mean that every project must use exactly the same package version in every situation.

There may be cases where a project requires special handling.

Before overriding a centrally managed version, however, consider whether the difference is actually necessary.

Keeping versions consistent whenever possible reduces dependency complexity.


๐Ÿ”„ Updating a Package Centrally

One of the biggest benefits of Central Package Management is updating a package version from one location.

For example, suppose you currently have:

<PackageVersion Include="Newtonsoft.Json"
                Version="13.0.3" />

You can update the central version:

<PackageVersion Include="Newtonsoft.Json"
                Version="13.0.4" />

Projects using that centrally managed package can then use the updated version.

This can be much easier than manually changing the same package version in many project files.


๐Ÿšจ Central Package Management and Dependency Conflicts

Central Package Management can help reduce version inconsistencies, but it does not automatically eliminate every NuGet dependency conflict.

Your project can still have direct and transitive dependencies that require different package versions.

For example:

Project
โ”‚
โ”œโ”€โ”€ PackageA
โ”‚   โ””โ”€โ”€ CommonPackage 1.x
โ”‚
โ””โ”€โ”€ PackageB
    โ””โ”€โ”€ CommonPackage 2.x

In situations like this, you still need to understand the dependency graph and determine which version is appropriate.

If you're troubleshooting a conflict, see:

๐Ÿ“ฆ How to Fix NuGet Package Version Conflicts in Visual Studio


๐Ÿ”Ž How to Inspect Transitive Dependencies

When troubleshooting package versions, it can be useful to inspect transitive dependencies.

dotnet list package --include-transitive

This can help reveal packages that your project receives indirectly.

For more information about the difference between direct and transitive dependencies, see:

๐Ÿ“ฆ Direct vs Transitive NuGet Dependencies: What's the Difference?


๐Ÿ“‹ Example: Complete Directory.Packages.props

Here is a simple complete example:

<Project>

  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>

  <ItemGroup>

    <PackageVersion Include="Newtonsoft.Json"
                    Version="13.0.3" />

    <PackageVersion Include="Serilog"
                    Version="4.0.0" />

    <PackageVersion Include="Microsoft.Extensions.Logging"
                    Version="9.0.0" />

  </ItemGroup>

</Project>

๐Ÿ“„ Example Project File

A project using those centrally managed packages can look like this:

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

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>

    <PackageReference Include="Newtonsoft.Json" />

    <PackageReference Include="Serilog" />

    <PackageReference Include="Microsoft.Extensions.Logging" />

  </ItemGroup>

</Project>

โœ… Benefits of Central Package Management


โš ๏ธ Things to Consider


โ“ Frequently Asked Questions

What is Central Package Management in .NET?

Central Package Management is a NuGet feature that allows package versions to be managed centrally, typically through a Directory.Packages.props file.

Where should Directory.Packages.props be located?

It is normally placed at a directory level that allows the relevant projects underneath it to inherit the central package configuration.

Do I need to specify Version in PackageReference?

When Central Package Management is enabled and a package version is centrally defined, the project can reference the package without specifying its version.

Does Central Package Management fix all NuGet conflicts?

No. It helps centralize versions and reduce inconsistencies, but dependency conflicts can still occur when packages have incompatible dependency requirements.


๐Ÿ“š Related NuGet Articles

๐Ÿ“ฆ How to Fix NuGet Package Version Conflicts in Visual Studio

๐Ÿ”ง How to Fix NU1107: Version Conflict Detected for NuGet Package

๐Ÿ” How to Check Which NuGet Package Is Causing a Dependency Conflict

๐Ÿ“ฆ Direct vs Transitive NuGet Dependencies: What's the Difference?

๐Ÿ”„ How to Update NuGet Packages Safely Without Breaking Your Project

๐Ÿ“ฆ PackageReference vs packages.config: Which Should You Use?


๐ŸŽฏ Conclusion

Central Package Management provides a cleaner way to manage NuGet package versions across multi-project .NET solutions.

Instead of repeating package versions throughout individual .csproj files, you can define them centrally in Directory.Packages.props.

This makes updating packages easier and can help keep dependencies consistent across your solution.

๐Ÿ“ฆ Managing NuGet packages across multiple projects?

Start centralizing your package versions with Directory.Packages.props and keep your solution's dependencies easier to maintain.

๐Ÿค– AlgoLassi Assistant Have a question about this tutorial?

Ask AlgoLassi and get an answer plus the tutorials worth studying next.

Ask a question

๐Ÿ’ฌ Comments

Sign in with Google to publish immediately, or comment anonymously and wait for approval.

Comments will appear here when available.