.NET Standard

.NET Standard is a formal specification of .NET APIs that are available on multiple .NET implementations. The motivation behind .NET Standard was to establish greater uniformity in the .NET ecosystem. However, .NET 5 adopts a different approach to establishing uniformity, and this new approach eliminates the need for .NET Standard in many scenarios. For more information, see .NET 5 and .NET Standard later in this article.

.NET implementation support

The various .NET implementations target specific versions of .NET Standard. Each .NET implementation version advertises the highest .NET Standard version it supports, a statement that means it also supports previous versions. For example, .NET Framework 4.6 implements .NET Standard 1.3, which means that it exposes all APIs defined in .NET Standard versions 1.0 through 1.3. Similarly, .NET Framework 4.6.1 implements .NET Standard 1.4, while .NET 5.0 implements .NET Standard 2.1.

The following table lists the minimum implementation versions that support each .NET Standard version. That means that later versions of a listed implementation also support the corresponding .NET Standard version. For example, .NET Core 2.1 and later versions support .NET Standard 2.0 and earlier versions.

.NET Standard 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0 2.1
.NET Core and .NET 5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0 3.0
.NET Framework 1 4.5 4.5 4.5.1 4.6 4.6.1 4.6.1 2 4.6.1 2 4.6.1 2 N/A3
Mono 4.6 4.6 4.6 4.6 4.6 4.6 4.6 5.4 6.4
Xamarin.iOS 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.14 12.16
Xamarin.Mac 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.8 5.16
Xamarin.Android 7.0 7.0 7.0 7.0 7.0 7.0 7.0 8.0 10.0
Universal Windows Platform 10.0 10.0 10.0 10.0 10.0 10.0.16299 10.0.16299 10.0.16299 TBD
Unity 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 TBD

1 The versions listed for .NET Framework apply to .NET Core 2.0 SDK and later versions of the tooling. Older versions used a different mapping for .NET Standard 1.5 and higher. You can download tooling for .NET Core tools for Visual Studio 2015 if you cannot upgrade to Visual Studio 2017 or a later version.

2 The versions listed here represent the rules that NuGet uses to determine whether a given .NET Standard library is applicable. While NuGet considers .NET Framework 4.6.1 as supporting .NET Standard 1.5 through 2.0, there are several issues with consuming .NET Standard libraries that were built for those versions from .NET Framework 4.6.1 projects. For .NET Framework projects that need to use such libraries, we recommend that you upgrade the project to target .NET Framework 4.7.2 or higher.

3 .NET Framework doesn't support .NET Standard 2.1. For more information, see the announcement of .NET Standard 2.1.

  • The columns represent .NET Standard versions. Each header cell is a link to a document that shows which APIs got added in that version of .NET Standard.
  • The rows represent the different .NET implementations.
  • The version number in each cell indicates the minimum version of the implementation you'll need in order to target that .NET Standard version.
  • For an interactive table, see .NET Standard versions.

To find the highest version of .NET Standard that you can target, do the following steps:

  1. Find the row that indicates the .NET implementation you want to run on.
  2. Find the column in that row that indicates your version starting from right to left.
  3. The column header indicates the .NET Standard version that your target supports. You may also target any lower .NET Standard version. Higher .NET Standard versions will also support your implementation.
  4. Repeat this process for each platform you want to target. If you have more than one target platform, you should pick the smaller version among them. For example, if you want to run on .NET Framework 4.8 and .NET 5.0, the highest .NET Standard version you can use is .NET Standard 2.0.

Which .NET Standard version to target

When choosing a .NET Standard version to target, consider this trade-off:

  • The higher the version, the more APIs are available to your library's code.
  • The lower the version, the more apps and libraries can use your library.

We recommend you target the lowest version of .NET Standard possible. So, after you find the highest .NET Standard version you can target, follow these steps:

  1. Target the next lower version of .NET Standard and build your project.
  2. If your project builds successfully, repeat step 1. Otherwise, retarget to the next higher version and that's the version you should use.

However, targeting lower .NET Standard versions introduces a number of support dependencies. If your project targets .NET Standard 1.x, we recommend that you also target .NET Standard 2.0. This simplifies the dependency graph for users of your library that run on .NET Standard 2.0 compatible implementations, and it reduces the number of packages they need to download.

.NET Standard versioning rules

There are two primary versioning rules:

  • Additive: .NET Standard versions are logically concentric circles: higher versions incorporate all APIs from previous versions. There are no breaking changes between versions.
  • Immutable: Once shipped, .NET Standard versions are frozen.

There will be no new .NET Standard versions after 2.1. For more information, see .NET 5 and .NET Standard later in this article.

Specification

The .NET Standard specification is a standardized set of APIs. The specification is maintained by .NET implementors, specifically Microsoft (includes .NET Framework, .NET Core, and Mono) and Unity.

Official artifacts

The official specification is a set of .cs files that define the APIs that are part of the standard. The ref directory in the dotnet/standard repository defines the .NET Standard APIs.

The NETStandard.Library metapackage (source) describes the set of libraries that define (in part) one or more .NET Standard versions.

A given component, like System.Runtime, describes:

  • Part of .NET Standard (just its scope).
  • Multiple versions of .NET Standard, for that scope.

Derivative artifacts are provided to enable more convenient reading and to enable certain developer scenarios (for example, using a compiler).

Package representation

The primary distribution vehicle for the .NET Standard reference assemblies is NuGet packages. Implementations are delivered in a variety of ways, appropriate for each .NET implementation.

NuGet packages target one or more frameworks. .NET Standard packages target the ".NET Standard" framework. You can target the .NET Standard framework using the netstandard compact TFM (for example, netstandard1.4). Libraries that are intended to run on multiple implementations of .NET should target this framework. For the broadest set of APIs, target netstandard2.0 since the number of available APIs more than doubled between .NET Standard 1.6 and 2.0.

The NETStandard.Library metapackage references the complete set of NuGet packages that define .NET Standard. The most common way to target netstandard is by referencing this metapackage. It describes and provides access to the ~40 .NET libraries and associated APIs that define .NET Standard. You can reference additional packages that target netstandard to get access to additional APIs.

Versioning

The specification is not singular, but a linearly versioned set of APIs. The first version of the standard establishes a baseline set of APIs. Subsequent versions add APIs and inherit APIs defined by previous versions. There is no established provision for removing APIs from the Standard.

.NET Standard is not specific to any one .NET implementation, nor does it match the versioning scheme of any of those implementations.

As noted earlier, there will be no new .NET Standard versions after 2.1.

Target .NET Standard

You can build .NET Standard Libraries using a combination of the netstandard framework and the NETStandard.Library metapackage.

.NET Framework compatibility mode

Starting with .NET Standard 2.0, the .NET Framework compatibility mode was introduced. This compatibility mode allows .NET Standard projects to reference .NET Framework libraries as if they were compiled for .NET Standard. Referencing .NET Framework libraries doesn't work for all projects, such as libraries that use Windows Presentation Foundation (WPF) APIs.

For more information, see .NET Framework compatibility mode.

.NET Standard libraries and Visual Studio

In order to build .NET Standard libraries in Visual Studio, make sure you have Visual Studio 2019 or Visual Studio 2017 version 15.3 or later installed on Windows, or Visual Studio for Mac version 7.1 or later installed on macOS.

If you only need to consume .NET Standard 2.0 libraries in your projects, you can also do that in Visual Studio 2015. However, you need NuGet client 3.6 or higher installed. You can download the NuGet client for Visual Studio 2015 from the NuGet downloads page.

.NET 5 and .NET Standard

.NET 5 is the implementation of .NET that Microsoft is actively developing. It's a single product with a uniform set of capabilities and APIs that can be used for Windows desktop apps and cross-platform console apps, cloud services, and websites. The .NET 5.0 TFMs reflect this broad range of scenarios:

  • net5.0

    This TFM is for code that runs everywhere. With a few exceptions, it includes only technologies that work cross-platform. For .NET 5 code, net5.0 replaces both netcoreapp and netstandard TFMs.

  • net5.0-windows

    This is an example of OS-specific TFMs that add OS-specific functionality to everything that net5.0 refers to.

When to target net5.0 vs. netstandard

For existing code that targets netstandard, there's no need to change the TFM to net5.0. .NET 5.0 implements .NET Standard 2.1 and earlier. The only reason to retarget 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 multitarget .NET 5.0 and .NET Standard to get access to newer features and still have your library available to other .NET implementations.

Here are some guidelines for new code for .NET 5:

  • App components

    If you're using libraries to break down an application into several components, we recommend you target net5.x where 5.x is the earliest .NET 5 version that your application can target. For simplicity, it's best to keep all projects that make up your application on the same version of .NET. Then you can assume the same BCL features everywhere.

  • Reusable libraries

    If you're building reusable libraries that you plan to ship on NuGet, consider the trade-off between reach and available feature set. .NET Standard 2.0 is the latest version that is supported by .NET Framework, so it gives good reach with a fairly large feature set. We don't recommend targeting .NET Standard 1.x, as you'd limit the available feature set for a minimal increase in reach.

    If you don't need to support .NET Framework, you could go with .NET Standard 2.1 or .NET 5. We recommend you skip .NET Standard 2.1 and go straight to .NET 5. 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.

.NET Standard problems

Here are some problems with .NET Standard that help explain why .NET 5 is the better way to share code across platforms and workloads:

  • Slowness to add new APIs

    .NET Standard was created as an API set that all .NET implementations would have to support, so there was a review process for proposals to add new APIs. The goal was to standardize only APIs that could be implemented in all current and future .NET platforms. The result was that if a feature missed a particular release, you might have to wait for a couple of years before it got added to a version of the Standard. Then you'd wait even longer for the new version of .NET Standard to be widely supported.

    Solution in .NET 5: When a feature is implemented, it's already available for every .NET 5 app and library because the code base is shared. And since there's no difference between the API specification and its implementation, you're able to take advantage of new features much quicker than with .NET Standard.

  • Complex versioning

    The separation of the API specification from its implementations results in complex mapping between API specification versions and implementation versions. This complexity is evident in the table shown earlier in this article and the instructions for how to interpret it.

    Solution in .NET 5: There's no separation between a .NET 5.x API specification and its implementation. The result is a simplified TFM scheme. There's one TFM prefix for all workloads: net5.0 is used for libraries, console apps, and web apps. The only variation is a suffix that specifies platform-specific APIs for a particular platform, such as net5.0-windows. Thanks to this TFM naming convention, you can easily tell whether a given app can use a given library. No version number equivalents table like the one for .NET Standard is needed.

  • Platform-unsupported exceptions at run time

    .NET Standard exposes platform-specific APIs. Your code might compile without errors and appear to be portable to any platform even if it isn't portable. When it runs on a platform that doesn't have an implementation for a given API, you get run-time errors.

    Solution in .NET 5: The .NET 5 SDK includes code analyzers that are enabled by default. The platform compatibility analyzer detects unintentional use of APIs that aren't supported on the platforms you intend to run on. For more information, see Platform compatibility analyzer.

.NET Standard not deprecated

.NET Standard is still needed for libraries that can be used by multiple .NET implementations. We recommend you target .NET Standard in the following scenarios:

  • Use netstandard2.0 to share code between .NET Framework and all other implementations of .NET.
  • Use netstandard2.1 to share code between Mono, Xamarin, and .NET Core 3.x.

See also