The release of .NET 5.0 in November 2020 marked a significant milestone for the .NET ecosystem.
Developers of reusable libraries especially need to understand:
- the change in approach to unify .NET Standard and .NET Core; and
- the new .NET 5.0 Target Framework Monikers (TFM).
In December 2014, Microsoft introduced .NET Core as a foundation for open source and cross-platform support, with the goal of .NET having a single code base.
In September 2016, Microsoft introduced the .NET Standard as a set of APIs that all .NET platforms have to implement.
In May 2019, Microsoft provided clarity on the future of .NET that:
- new applications should be built on .NET Core 3.0+; and
- .NET Framework 4.8 will be the last major version of .NET Framework (to be supported as long as Windows itself is supported).
At the same time, Microsoft introduced the vision for .NET 5 as the combination of “.NET Core and the best of Mono to create a single platform that you can use for all your modern .NET code”.
Unification of .NET Standard and .NET Core
Retrospectively, the approach of the .NET Standard has been very successfully to provide uniformity within the .NET ecosystem. It also has suffered from a number of issues, including the delay between specification changes and the implementation of those changes in the individual platform code bases.
.NET 5.0 adopts a different approach to establishing uniformity within the .NET ecosystem.
.NET 5.0 is the beginning of a single cross-platform .NET runtime and framework implementation that unifies .NET Core and the .NET Standard. It provides the same runtime behaviours and developer experiences across all platforms with a set of APIs, languages, and tools that target a broad set of application types, including: mobile, cloud, desktop, and IoT.
Microsoft will NOT be releasing a new version of .NET Standard. .NET 5 and all future versions will continue to support .NET Standard 2.1 and earlier, and should be considered the foundation for all new code.
.NET 5.0 Target Framework Monikers (TFM)
net5.0 is the new Target Framework Moniker (TFM) for .NET 5.0.
It combines and replaces the
netstandard TFMs that are specified in project files.
1<Project Sdk="Microsoft.NET.Sdk"> 2 3 <PropertyGroup> 4 <TargetFramework>net5.0</TargetFramework> 5 </PropertyGroup> 6 7</Project>
Multiple frameworks can be targeted, using
<TargetFrameworks> as per the following example.
1<Project Sdk="Microsoft.NET.Sdk"> 2 3 <PropertyGroup> 4 <TargetFrameworks>net5.0;netstandard2.0</TargetFrameworks> 5 </PropertyGroup> 6 7</Project>
net5.0-windows will be used to expose Windows-specific functionality, including Windows Forms, WPF and WinRT APIs.
.NET 6.0 will use the same approach, with
net6.0, and will add
Guidance on Targeting .NET 5.0 vs .NET Standard
Microsoft have updated their documentation to provide guidance on when to target net5.0 vs. netstandard.
The only reason to re-target from .NET Standard to .NET 5.0 would be to gain access to more runtime features, language features, or APIs.
For example, in order to use C# 9, you need to target .NET 5.0.
You can multi-target .NET 5.0 and .NET Standard to get access to newer features and still have your library available to other .NET implementations.
Most widely used libraries will end up multi-targeting for both .NET Standard 2.0 and .NET 5.
Supporting .NET Standard 2.0 gives you the most reach, while supporting .NET 5 ensures you can leverage the latest platform features for customers that are already on .NET 5.
TFM Usage Cheat Sheet
Here is the Cheat Sheet for guidance on TFM usage:
- do NOT target .NET Standard 1.x for new libraries (.NET Core 1.x is end-of-life and is no longer supported);
- target a minimum of
netstandard2.0if you want to support minimum usage of .NET Core 2.x or .NET Framework (from 4.6.1). See .NET Standard Versions for more information on version compatibility;
- target a minimum of
netstandard2.1if you want to support minimum usage of .NET Core 3.x or share code between Mono, Xamarin, and .NET Core 3.x; and
- target a minimum of
net5.0if you do NOT need to support the .NET Core 2.x, .NET Core 3.x or .NET Framework (from 4.6.1).
Boiling it all down to one sentence: in order to enable the largest reach of your library, multi-target both
Extra Guidance on Targeting .NET Standard 1.x
If you have an existing library that already targets .NET Standard 1.x:
- keep targeting .NET Standard 1.x in order to maintain compatibility with existing usage of your library;
- understand that .NET Standard 1.x is distributed as a granular set of NuGet packages, which creates a large package dependency graph and results in developers downloading a lot of packages when building, so seriously consider additionally multi-targeting with
net5.0to provide a better experience for developers using later versions of .NET.