Make Sitecore 10.3 → 10.4 Upgrades Easier with Central Package Management

By , Senior Full-Stack Engineer15 min read

Planning a Sitecore upgrade from 10.3 to 10.4.1 typically involves the dread of manually updating package versions across multiple project files. This painful process has been a source of frustration for many developers, but there's a better way. NuGet Central Package Management (CPM) is a feature that completely transforms the upgrade experience. What used to be a complex, error-prone process becomes streamlined and reliable. Here's exactly how to implement CPM and revolutionize your Sitecore upgrade workflow.

The Problem: Traditional Sitecore Package Management Pain

Before implementing Central Package Management, most Sitecore solutions look like typical enterprise implementations:

Here's what the pre-CPM upgrade process typically looks like:

  • Search through multiple project files for Sitecore package references
  • Manually update each Version="10.3.0" to Version="10.4.1"
  • Handle inconsistent version patterns across projects
  • Deal with the Update attribute pattern used for core Sitecore packages
  • Hope you don't miss any packages or create version conflicts
  • Troubleshoot restore and build errors across multiple files

Enter Central Package Management: The Game Changer

Central Package Management is a NuGet feature that allows you to manage all package versions in a single Directory.Packages.props file at your solution root. Instead of specifying versions in individual project files, projects reference packages by name only, and versions are supplied centrally.

The benefits for Sitecore solutions are transformative:

  • Single source of truth for all package versions
  • Guaranteed consistency across all projects
  • Simplified upgrades with one-file changes
  • Clear visibility into all dependencies
  • Easier conflict resolution and debugging
  • Perfect for Sitecore's many interdependent packages

Implementation Step-by-Step

Step 1: Enable CPM in Directory.Build.props

First, enable Central Package Management at the solution level by adding one property to the existing Directory.Build.props file:

<Project>
  <PropertyGroup>
    <!-- Add this line to enable Central Package Management -->
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
</Project>

Step 2: Create Directory.Packages.props

Next, create the Directory.Packages.props file at the solution root. This becomes the single source of truth for all package versions:

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

  <!-- Group packages logically for better maintainability -->
  <ItemGroup Label="Microsoft">
    <PackageVersion Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="4.1.0" />
  </ItemGroup>

  <ItemGroup Label="Sitecore Core">
    <PackageVersion Include="Sitecore.Kernel" Version="10.4.1" />
    <PackageVersion Include="Sitecore.Mvc" Version="10.4.1" />
  </ItemGroup>

  <ItemGroup Label="Sitecore SXA">
    <PackageVersion Include="Sitecore.XA.Foundation.IOC" Version="10.4.1" />
    <PackageVersion Include="Sitecore.XA.Foundation.MarkupDecorator" Version="10.4.1" />
    <PackageVersion Include="Sitecore.XA.Foundation.Multisite" Version="10.4.1" />
    <PackageVersion Include="Sitecore.XA.Foundation.Mvc" Version="10.4.1" />
    <PackageVersion Include="Sitecore.XA.Foundation.RenderingVariants" Version="10.4.1" />
    <PackageVersion Include="Sitecore.XA.Foundation.Variants.Abstractions" Version="10.4.1" />
  </ItemGroup>
</Project>

Step 3: Update Project Files

The most time-consuming part is updating all project files to remove version attributes from PackageReference elements. Here's what a typical transformation looks like:

<!-- BEFORE: Traditional package references -->
<ItemGroup>
  <PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="4.1.0" />
  <PackageReference Include="Sitecore.Kernel" />
  <PackageReference Include="Sitecore.Mvc" />
  <PackageReference Include="Sitecore.XA.Foundation.Mvc" Version="10.4.1" />
</ItemGroup>
<ItemGroup>
  <!-- Update pattern commonly used in Sitecore projects -->
  <PackageReference Update="Sitecore.Kernel" Version="10.4.1" />
  <PackageReference Update="Sitecore.Mvc" Version="10.4.1" />
</ItemGroup>

<!-- AFTER: Central Package Management -->
<ItemGroup>
  <PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" />
  <PackageReference Include="Sitecore.Kernel" />
  <PackageReference Include="Sitecore.Mvc" />
  <PackageReference Include="Sitecore.XA.Foundation.Mvc" />
  <!-- Remove all Update entries - versions now come from Directory.Packages.props -->
</ItemGroup>

Key changes to make in each project file:

  • Remove all Version attributes from PackageReference elements
  • Delete all PackageReference Update entries (this pattern is no longer needed)
  • Ensure Include references exist for packages that were previously only Update entries
  • Preserve other attributes like PrivateAssets and IncludeAssets

Step 4: Validate the Implementation

After updating all project files, validate that everything works correctly:

# Clean and restore to verify package resolution
dotnet clean
dotnet restore

# Build to ensure no missing references
dotnet build

Validation may reveal missing PackageVersion entries in Directory.Packages.props, which can be added quickly. CPM makes these errors immediately obvious and straightforward to resolve.

The Upgrade Transformation: 10.3 → 10.4.1 Simplified

With Central Package Management in place, upgrading from Sitecore 10.3 to 10.4.1 becomes almost trivially easy. Here's the entire process:

The Old Way (Without CPM)

  1. Open each project file individually
  2. Search for Version="10.3.0" in each file
  3. Replace with Version="10.4.1" carefully
  4. Handle inconsistent version formats and patterns
  5. Track which files have been updated
  6. Run restore and fix inevitable conflicts
  7. Debug missing packages and version mismatches
  8. Repeat until everything builds cleanly

This approach is complex, error-prone, and requires careful attention to avoid version conflicts.

The New Way (With CPM)

  1. Open Directory.Packages.props
  2. Find and replace 10.3.0 → 10.4.1
  3. Save the file
  4. Run dotnet restore
  5. Build and test

This approach is streamlined, reliable, and eliminates version inconsistencies.

<!-- The entire upgrade in one file change -->
<ItemGroup Label="Sitecore Core">
  <PackageVersion Include="Sitecore.Kernel" Version="10.4.1" />
  <PackageVersion Include="Sitecore.Mvc" Version="10.4.1" />
</ItemGroup>

<ItemGroup Label="Sitecore SXA">
  <!-- Same pattern for all SXA packages -->
  <PackageVersion Include="Sitecore.XA.Foundation.IOC" Version="10.4.1" />
  <PackageVersion Include="Sitecore.XA.Foundation.MarkupDecorator" Version="10.4.1" />
  <!-- ... all other packages -->
</ItemGroup>

Real-World Benefits

Dramatic Time Savings

The most significant benefit is dramatic workflow improvement. What used to be a complex, multi-step process becomes streamlined and reliable. These benefits extend beyond the initial upgrade:

TaskBefore CPMAfter CPMImpact
Package UpgradesComplex multi-file updatesSingle file changeDramatically simplified
Version ConflictsManual conflict resolutionAutomatic consistencyEliminated entirely
Security UpdatesUpdate across all projectsUpdate once centrallyStreamlined process
Adding New PackagesAdd to each project individuallyAdd once to central fileConsistent deployment

Eliminated Version Conflicts

Without CPM, version conflicts are a constant source of frustration. Different projects reference different versions of the same package, leading to binding redirect issues and runtime errors. With CPM, this becomes impossible - every project uses the exact same version, guaranteed.

Improved Code Review Process

Code reviews for package updates become much simpler. Instead of reviewing changes across multiple project files, reviewers can see all version changes in a single file. This makes it easier to:

  • Spot inconsistent version upgrades
  • Understand the full scope of changes
  • Verify security updates were applied consistently
  • Review upgrade compatibility across package groups

Better Dependency Visibility

Having all package versions in one file provides unprecedented visibility into solution dependencies. It becomes much easier to answer questions like:

  • Which packages need security updates?
  • Are we using consistent versions across all Sitecore packages?
  • What's the impact of upgrading a particular package?
  • Which packages are we actually using vs. legacy references?

Advanced Patterns and Best Practices

Logical Package Grouping

Organizing packages into logical groups makes the Directory.Packages.props file much more maintainable:

<Project>
  <!-- Group by vendor/purpose for easier maintenance -->
  <ItemGroup Label="Microsoft Framework">
    <PackageVersion Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="4.1.0" />
    <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
  </ItemGroup>

  <ItemGroup Label="Sitecore Core - Keep versions aligned">
    <PackageVersion Include="Sitecore.Kernel" Version="10.4.1" />
    <PackageVersion Include="Sitecore.Mvc" Version="10.4.1" />
  </ItemGroup>

  <ItemGroup Label="Sitecore SXA - Must match Core version">
    <PackageVersion Include="Sitecore.XA.Foundation.IOC" Version="10.4.1" />
    <!-- All SXA packages... -->
  </ItemGroup>

  <ItemGroup Label="Third-Party Dependencies">
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
    <PackageVersion Include="AutoMapper" Version="12.0.1" />
  </ItemGroup>
</Project>

Version Alignment for Sitecore Packages

One crucial pattern is keeping all Sitecore-related packages on the same version. Sitecore's ecosystem is tightly coupled, and version mismatches can cause subtle runtime issues:

Global Package References

For packages that every project should have (like analyzers or build tools), use GlobalPackageReference:

<ItemGroup Label="Global - Applied to all projects">
  <GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.*">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>analyzers</IncludeAssets>
  </GlobalPackageReference>
</ItemGroup>

Handling Legacy Dependencies

Some older Sitecore packages still require specific handling. For these cases, document the reasoning directly in the props file:

<ItemGroup Label="Legacy - Keep on older versions for compatibility">
  <!-- This package has breaking changes in newer versions -->
  <PackageVersion Include="LegacyLibrary" Version="2.1.0" />

  <!-- TODO: Upgrade when Sitecore 10.5 is released -->
  <PackageVersion Include="CompatibilityLibrary" Version="1.5.2" />
</ItemGroup>

Troubleshooting Common Issues

Missing Package Versions

The most common issue after implementing CPM is restore errors for missing PackageVersion entries. These are straightforward to fix:

error NU1008: Projects that use central package version management should not define the version on the PackageReference items but on the PackageVersion items

Solution: Add the missing package to Directory.Packages.props or remove the Version attribute from the project file.

Build Errors After Project Updates

If you see build errors after removing version attributes, check for:

  • Packages that were only defined with Update attributes (need Include entries)
  • Typos in package names between Directory.Packages.props and project files
  • Missing ManagePackageVersionsCentrally property in Directory.Build.props
  • Cached NuGet packages (try clearing with dotnet nuget locals all --clear)

Performance Considerations

CPM often improves restore performance because NuGet can resolve all versions centrally before processing individual projects. However, very large Directory.Packages.props files (100+ packages) can slow down Visual Studio's IntelliSense. Grouping and commenting can help mitigate this.

Migration Strategy for Existing Solutions

If you're considering implementing CPM in an existing Sitecore solution, here's a phased approach that works well:

Phase 1: Preparation

  1. Audit all package references across your solution
  2. Document current versions and identify inconsistencies
  3. Create a backup branch or tag before making changes
  4. Ensure you have a clean build before starting

Phase 2: Implementation

  1. Enable CPM in Directory.Build.props
  2. Create Directory.Packages.props with all current packages
  3. Update project files (can be scripted for large solutions)
  4. Validate restore and build work correctly

Phase 3: Testing and Refinement

  1. Test all major application functionality
  2. Run full regression tests if available
  3. Organize packages into logical groups
  4. Document any special version requirements

References and Further Reading

For additional information and official documentation on the topics covered in this guide:

The Future of Sitecore Package Management

Implementing Central Package Management is one of the best technical decisions for Sitecore solutions. The transformation from a complex, error-prone upgrade process to a simple, reliable workflow streamlines development and eliminates a major source of technical debt.

The benefits extend far beyond just upgrades:

  • ✅ Dramatically faster package updates and upgrades
  • ✅ Zero version conflicts between projects
  • ✅ Improved code review process and change visibility
  • ✅ Better dependency management and security update tracking
  • ✅ Simplified onboarding for new team members
  • ✅ Future-ready architecture for upcoming Sitecore releases

Key Recommendations

If you're managing a Sitecore solution with multiple projects, implement Central Package Management before your next upgrade. The upfront investment will provide immediate benefits and continue to streamline every future update.

Start with the basic implementation, then evolve your Directory.Packages.props file with logical groupings, comments, and advanced patterns as your solution grows. The key is to get started - even a basic CPM implementation is dramatically better than managing versions across multiple project files.

Central Package Management isn't just a nice-to-have feature - it's an essential tool for any serious Sitecore development team. It transforms package management from a source of friction into a competitive advantage, letting you focus on building great solutions instead of wrestling with dependency management.

Contact

Drop me a line. I read everything and reply within a day.

Required fields are marked “(required)”.