Free Pack
Download BuildMaster Free Trial

.NET 5/6+ Migration Strategies for Your NuGet Package Libraries

by Eric Seng, on Oct 26, 2020 8:17:00 AM

(This article was updated November 17, 2021 to reflect .NET 6's release.)

Choosing how—or even whether—to migrate your NuGet package libraries from .NET Framework to .NET 5/6+ depends on each application. Choose between five migration methods: abandon, update, fork, multi-target, or bridge.

NET 6 Delivery

Planning the migration of various .NET applications and NuGet libraries to .NET Core “vNext” (.NET 5/6+) is complicated. You likely have many applications and a lot of libraries, all in different lifecycle stages, ranging from ancient to still-being-planned. You can’t migrate your existing applications until you migrate your libraries.

But this presents a problem:

  • .NET 5/6+ applications cannot use .NET Framework libraries
  • .NET Framework applications cannot use .NET 5/6+ libraries

Therefore, how can you possibly migrate your libraries from .NET Framework to the new .NET?

There are five options for migrating your libraries to target a new .NET platform: abandon, update, fork, multi-target, or bridge.

In this article, we explain what each option entails, when you might want to choose it, and how to execute on that option. We start with the simplest option, but keep in mind that you must assess your applications, libraries, and migration plans to determine which option is best in each case.

Choice 1: AbandonPentad_Abandon

If you have no plan to ever move your library to .NET 5/6+, it will remain a .NET Framework library forever, receiving only small updates over the course of its lifetime.

What Abandon
When Libraries using deprecated technologies
Pro No extra/new work
Con  Library will never be usable in .NET 5/6+ and will be only usable on an unsupported OS once the operating system goes out of support
How Continue maintaining the library minimally and only as needed

When to Choose

“Abandon” is appropriate for a library that makes heavy use of technologies deprecated or not part of .NET 5/6+ (Web Forms, WCF, and WF). There will be many applications and libraries at your organization that use “old” technology, but which will persist indefinitely without needing to be rewritten. Web Forms applications are a great example.


Perhaps you have a library called Kramerica.WCF.Utils that you use only in WCF-based applications. Since WCF will never be part of .NET 5/6+, there is no point migrating that library. Just maintain Kramerica.WCF.Utils minimally and only as needed.

Choice 2: UpdatePentad_Update

“Updating” your libraries means migrating from .NET Framework to .NET 5/6+ while keeping some “room” in the version numbers for emergency releases.

What Update
When Most applications will use .NET 5/6+ but some old applications using .NET Framework endure
Pro Leaves room to “fork after-the-fact” in emergencies (i.e., you can roll back to an older version)
Con Must maintain the original library until the new is released
How Leave room between the .NET Framework library’s last version number and the first .NET 5/6+ version number

When to Choose

If you’re going to be migrating ALL your applications in a short amount time, it’s fine to update your old libraries and migrate to the new all at once. This option is also appropriate for libraries only being consumed by a very small number of applications.

How to Execute

Libraries are versioned. When you retarget, fix the code errors, and publish the “new” library, use a significantly higher major version number.

Using a big version bump (for example, Kramerica.Utils 2.6 up to Kramerica.Utils 5.0) communicates to consumers that there is a significant difference between the libraries. But perhaps more importantly, it provides enough versions between old and new to allow rollbacks. In an emergency situation, you can essentially to go “back in time” and create a new version of an old library—essentially, you “fork after the fact.”


Kramerica.MVC.Utils uses MVC technology, which can be migrated to 5/6+. This library could be updated with minimal changes when migrated. When migrating, you version the “old” library Kramerica.MVC.Utils 3.1, and you version the “new” to Kramerica.MVC.Utils 5.0.

Choice 3: Fork Pentad_Fork

Like choosing File > Save As on a Microsoft Word document before making changes, “forking” copies all the same source code into a separate repository. After copying, you can migrate in your libraries, target the new .NET platform, and you’ve got a whole new library without altering or removing the old one.

What Fork
When Framework and 5/6+ applications that will coexist in the mid-to-long-term
Pro New library and old library start the same but then continue independent of each other
Con Multiple, sometimes very similar codebases to maintain, release, and keep “in sync”
How Copy the library, retarget, fix the code errors, publish with a new name

When to Choose

If you’re going to need the .NET Framework version of your library for the mid- to long-term, you should fork. You may also consider this option if the migration will be complicated (as when parts of the .NET Framework in your library don’t exist in .NET 5/6+).

A guideline for forking is where 80-90% of the code will “overlap” but 10-20% are sufficiently different, it makes sense to fork. When this ratio is reversed or when the migration is trivial, forking will leave you with two, nearly identical codebases to maintain and release separately.

How to Execute

This is a relatively short, four-step process:

  1. Fork the current library.
    Copy the source code and rename the project/repository similarly, such as Utils to UtilsCore.
  2. In the fork, change what Visual Studio will target.
    If you tried to compile after this step, you would almost certainly get errors.
  3. Fix errors created by the retargeting and test.
    Repeat this step until you are error-free.
  4. Publish the library with its new name.


Kramerica.Network.Utils is forked to create Kramerica.NetworkCore.Utils.

Choice 4: Multi-target  Pentad_Multitarget

Creating a single NuGet package library that contains both versions of your libraries (the .NET Framework version and the .NET 5/6+ version). This is very efficient, because Visual Studio decides which .NET platform to target.

What Multi-target
When Efficiently supporting multiple applications on different .NET platforms and keeping libraries in sync
Pro One library is usable in both .NET Framework and .NET 5/6+
Con Multi-targeted code is complicated to write and maintain
How Create one NuGet package with both (or more) libraries inside it

Consider movies as an analogy: If you buy the original Star Wars trilogy in hard copy, you’ll find a set of DVDs and Blu-ray discs in the same package, so you can play the film on whichever player you have at home. You have both choices at the same time, just like a multi-targeted NuGet package. (A note, though: while most Blu-ray players can now play DVDs, we have no evidence from Microsoft that .NET 5/6+ will ever be able to use Framework libraries.)

When to Choose

Creating a new application, you tell Visual Studio what .NET platform you’re targeting. If you’ve created a multi-targeted NuGet library, Visual Studio can select the right library from the different choices each time it compiles, saving you time.

Choose multi-targeting in situations where the .NET Framework library and the .NET 5/6+ library will be substantially similar, even if the “newer” library has different or additional functionality. (Blu-rays can do more than DVDs, but it’s still the same movie!) This is a great option if the codebase will remain mostly the same.

Be careful, though. There is a lot of information out there about multi-targeting, so it can be very hard to know whether you’re getting helpful advice.

How to Execute

When you compile C# code, you can pick what type of assembly you want, such as .NET Framework or .NET 5/6+. A NuGet package (zip file) has libraries under a subfolder named after the type of assembly. In this way, a NuGet package can have both a .NET Framework library (under the .net452 folder to specify version 4.5.2), or a .NET 5/6+ library (under the net5.0 folder).

The general concept to getting this to work is twofold:

  1. Configure your project to compile/build multiple times: once for each platform you want to target (for example, .NET Framework 4.5.2 and .NET 5.0).
  2. Build a NuGet package out of all of those assemblies.

For detailed instructions, consult the documentation for Windows use or for Visual Studio for Mac.


Kramerica.Data.Models goes from being a NuGet package that contains only a single Framework 4.8-compatible library to a package that contains multiple libraries, Kramerica.Data.FrameworkModels and Kramerica.Data.CoreModels.

Choice 5: BridgePentad_Bridge

If you’re lucky and your library’s code just happens to be compatible with a now-deprecated technology called NET Standard 2.0, then you may be able to create a library that works in both .NET Framework and .NET 5/6+ without the complexity of multi-targeting.

What Bridge
When Buy time before making another choice (only if your code supports it)
Pro One library is usable in both .NET Framework and .NET 5/6+
Con Adopting a deprecated technology that will keep the library “locked” to .NET Framework’s functionality
How Changing your library’s targeting to .NET Standard 2.0


.NET Standard was a predecessor to .NET Core and was Microsoft’s attempt to unify all the .NET platforms prior to .NET 5/6+. It’s a confusing technology, but the bottom line is that it may be a good choice if your libraries are already targeting.NET Framework 4.7.2 or later.

Continuing the Star Wars DVDs and Blu-rays in the same package analogy, targeting .NET Standard 2.0 is like releasing a single disc (let’s call it a “BluDVD”) that’s simultaneously a DVD and Blu-ray disc and can be played in most Blu-ray and DVD players.

When to Choose

This is a simpler but temporary alternative to multi-targeting. It only works if your library is currently targeting .NET Framework 4.7.2 or later. It is a way to buy time while you migrate your applications to .NET 5/6+. You will eventually need to settle on one of the other four choices for your libraries.

Instead of having a single NuGet package with two “substantially similar” libraries, this approach will yield a single library that is “locked” to whatever is available in .NET Framework 4.7.2. That might be okay, depending on the contents of your library.

With multi-targeting, you can introduce additional functionality in the .NET 5/6+ code for new applications. Over time, you have migrated all of your consuming applications to .NET 5/6+, you can simply remove the .NET Framework targeting from your library and return to a simple package. None of this is possible with the .NET Standard “bridge” approach.

How to Execute

This process basically the same as “update,” though there is a higher chance for errors, which may be motivation to select a different method.

  1. In your library, change what Visual Studio will target to .NET Standard 2.0.
  2. Evaluate the errors and incompatibilities that Visual Studio reports.
    Look for errors that will require substantial code changes
  3. Then, either…
    Fix the errors (and test then repeat as needed) and publish the library with the new targeting
    Choose another migration method

Related Questions with Resources

It’s easy to end up in a multi-targeting rabbit hole as you research. To save you time, we’ve answered many common questions with some good resources to check out.

What else is multi-targeting good for, besides a way to manage libraries for different platforms?

Multi-targeting is also a mindset for migrating applications. This is what we do with ProGet. You can build an application as .NET 5/6+ AND .NET Framework, then test these versions side-by-side. This lets you deploy the “newer”-platformed version to production, and if there’s a problem, quickly switch to the .NET Framework application. It’s like insurance.

What does multi-targeting look like “in real life”?

To see how to port from one library to another, check out Rick Strahl’s “Multi-targeting and Porting a .NET Library to .NET Core 2.0.” To learn about multi-targeted applications, read Brad Robinson’s “Non-Trivial Multi-Targeting with .NET.”

How can I target in SDK projects?

Microsoft gives us detailed documentation on SDK-style projects.

How do I develop for multiple platforms with .NET Framework?

It’s not terribly difficult, actually! But read Microsoft’s instructions to make sure you get it right.

Can I target multiple operating systems in one NuGet package?

This piece about .NET Standard is a bit dated but gives some instruction. .NET 5/6+ explicitly considers cross-platform development. This Microsoft documentation helps explain this, under the heading “When to Choose .NET 5/6+"

How does this relate to .NET Multi-Targeting Packs?

For the choices we discussed in this article, you do not need to worry about multi-targeting packs. But for those interested, this technical question is best answered by “additional reading” on what a multi-targeting pack even is and guidelines for use.

How does this relate to .NET Multi-platform App UI (MAUI)?

For the choices we discussed in this article, MAUI is unrelated. But for those interested, you can learn more about MAUI via Microsoft.

Hit the Right Target

.NET 5/6+ marks a new era in .NET development. But not all your applications and libraries will be immediately affected. Don’t rush headlong into migrating. Instead, make better decisions—and ultimately use fewer organizational resources—by assessing and planning which libraries should be abandoned, updated, forked, multi-targeted, or bridged.

Get a Copy of the .NET 5/6+ Migration Guide

The migration to .NET 5/6+ from .NET Framework has many complications and, as we've discussed, many options for how and when to migrate. We’ve built a guide on how to successfully migrate to .NET 5/6+ and beyond. Get your copy today!


Related Posts

About Inedo

Inedo is a software product company bringing you the "tech behind the tech."

Makers of Windows-first, enterprise DevOps tools BuildMaster CI/CD, ProGet private package management, and Otter IaC. Maximize developer time, minimize release risk, and empower stakeholders to bring their vision to life faster, all with the people and technology you have right now.

Follow us on social media

Follow Inedo on YouTube Follow Inedo on Facebook Follow Inedo Twitter New call-to-action

Free e-books

Free PowerShell Book NuGet for the Enterprise Guide Jenkins CICD Guide Free CICD Book Free dotnet book free IaC book