Update on .NET Standard adoption

Avatar

Immo

It’s about two years ago that I announced .NET Standard 2.0. Since then we’ve been working hard to increase the set of .NET Standard-based libraries for .NET. This includes many of the BCL components, such as the Windows Compatibility Pack, but also other popular libraries, such as the JSON.NET, the Azure SDK, or the AWS SDK. In this blog post, I’ll share some thoughts and numbers about the .NET ecosystem and .NET Standard.

Adoption by the numbers

In order to track adoption, we’re looking at nuget.org. On a regular interval, we check whether new package versions add support for .NET Standard. Once a package ID does, we stopped looking at future versions. This allows us to track when a package first adopted .NET Standard.

For the purposes of measuring adoption in the ecosystem, we’ve excluded all packages that represent the .NET platform (e.g. System.*) or were built by Microsoft, e.g. Microsoft.Azure.*. Of course, we track that too, but as part of pushing first parties to adopt .NET Standard.

This is what the adoption looks like:

  • On nuget.org:
    • 47% of the top one thousand packages support .NET Standard
    • 30% of all packages support .NET Standard (about 48k out of 160k packages)
  • Generously adding trendlines, we could expect ~100% by around 2022
    • Trendlines border on using a magic 8 ball, so take these figures with a big jar of salt.
    • We’ll likely never get to a 100% but it seems to suggest that we can expect maximum reach within the next two to three years, which seems realistic and is in line with our expectations.

What should I do?

With few exceptions, all libraries should be targeting .NET Standard. Exceptions include UI-only libraries (e.g. a WinForms control) or libraries that are just as building blocks inside of a single application.

In order to decide the version number, you can use the interactive version picker. But when in doubt, just start with .NET Standard 2.0. Even when .NET Standard 2.1 will be released later this year, most libraries should still be on .NET Standard 2.0. That’s because most libraries won’t need the API additions and .NET Framework will never be updated to support .NET Standard 2.1 or higher.

This recommendation is also reflected in the .NET library guidance we published earlier (taken from the cross-platform targeting section):

✔️ DO start with including a netstandard2.0 target.

Most general-purpose libraries should not need APIs outside of .NET Standard 2.0. .NET Standard 2.0 is supported by all modern platforms and is the recommended way to support multiple platforms with one target.

There are some reasons why you may want to update to .NET Standard 2.1. The primary reasons would be:

  • Wide support for Span<T>
    • We’ve added various new methods across the BCL to support span-based APIs for writing allocation free code
  • New language features

Summary

.NET Standard adoption is already quite high, but it’s still growing. Please continue to update the packages you haven’t updated yet. And when creating new packages, continue to start with .NET Standard 2.0, even after .NET Standard 2.1 has shipped.

Happy coding!

Avatar
Immo Landwerth

Program Manager, .NET

Follow Immo   

30 comments

  • Avatar
    Peter

    So MSFT still thinks the libs on Nuget are in any way representative for the thousands of commercial 3rd party libs in use by Enterprise/Medical/Financial etc. devs? Libs for image processing, sophisticated 3rd party WPF controls, libs for license management, libs for financial services, for payment processing. All this kind of expensive 3rd party libs we  “uncool” devs use, often are forced to use by regulation or customer contracts. None of this stuff is on Nuget and the Net Standard adaption in this area is pretty close to zero.

    And by the way: Would MSFT mind to finaly fix the comment system of this blog?

    • Avatar
      Jorge Morales

      As the article says, if you still rely on desktop libraries (Windows Forms or WPF), then stick with .NET Framework, it will still be present in Windows. However, if you think that your “uncool” applications will still be around in the next few years, consider migrating to the “cool” new technologies, you already have the Windows Compatibility Pack, the .NET Portability Analyzer, and many other resources to plan your migration. I don’t know why people expect Microsoft to fix their work when everything is already available for them. I agree with only one thing: the comment section on this blog.

    • Avatar
      Immo Landwerth

      > So MSFT still thinks the libs on Nuget are in any way representative for the thousands of commercial 3rd party libs in use by Enterprise/Medical/Financial etc. devs?

      That wasn’t my intention. But we don’t have data for internal libraries. Also for internal libraries or commerical UI libraries, .NET Standard is also much less relevant. It’s mostly relevant for general purpose utility libraries, which NuGet is a good representation for.

      But I’ve got zero doubts that internal adoption isn’t lagging behind. At the same time, internal components are also “more under your control”. Not in all cases, but generally speaking. So it makes more sense to measure the external ecosystem as a measure of “how easy is life for me as a .NET Standard library author”.

      Does that make sense?

  • Avatar
    Jesper Jensen Nørregaard

    Hi,
    What is the story around C#8 and .Net Standard 2.0.
    Should I just use C#8, and rely on tooling to only allow usage of compatible features?

  • Avatar
    Martin Sedlmair

    The problem is that .NET Standard is always after .NET Core. So many features are still not available. Span<T> is one example. We switched to .NET Standard but then Span<T> came which is only available in .NET Core. So to be up-to-date you must need to switch to .NET Core. It would be better if .NET Standard gets updated first and then .NET Core.

    • Avatar
      Lex Mitchell

      I think you should still be able to create a library using .Net Standard and reference the System.Memory Nuget package to have access to Span. This is the case for a number of libraries omitted from the Standard (although not all)

    • Avatar
      Immo Landwerth

      Span<T> is available for .NET Standard 2.0 via a NuGet package. Of course, this doesn’t get you new APIs on, say, Stream, that accept spans yet.

      The point of .NET Standard is reach across multiple .NET implementations. By definition, this lags behind because it takes time to take the new concepts from .NET Core and put them elsewhere. If you wouldn’t use .NET Standard and instead compiled code by hand for different .NET implementations (.NET Core, .NET Framework, Xamarin, Unity) you’d run into the same limitation. So in that sense that’s not a problem of .NET Standard — that’s just reality.

      > It would be better if .NET Standard gets updated first and then .NET Core.

      How is .NET Standard useful if there are no platforms that implement it yet? You wouldn’t be able run the code you just compiled.

  • Avatar
    Lex Mitchell

    Given that the .Net Framework is no longer supporting new versions of the Standard and .Net Core will be able to run on the Mono runtime by the time of .Net 5, it really feels that most of the point in having a separate standard has gone. I can see it being useful for a few more transitional years, but will it continue after that?

    • Avatar
      Immo Landwerth

      You’re not wrong. In .NET 5, the hope is that innovating will get faster because we a unified implementation. However, you still need a way to write code that works across all OS platforms (e.g. Windows, Linux, iOS, Android) as well as code that is specific to those platforms. Today, we’re using framework names (netcoreapp, xamarin.ios, netstandard etc) to express that. We’ll still need a concept for that. So in that world, you can think of .NET Standard as API set that is everywhere, rather than as a spec that multiple different implementations provide.

  • Avatar
    Jukka Snellman

    I also don’t see the point of .NET Standard 2.1. I have tons of projects that will be stuck with .NET Framework, pending rewrite, and I’m sure I’m not the only one, considering it’s no easy task. So 2.0 is definitely relevant, but once you’re in .NET Core/5, might as well target that directly.

    • Avatar
      Hall, Trevor

      Same here.
      I work for a very large commercial company. We make many produts, including “Clinical diagnotics” and “medical devices”. None of our tools end up on “public nuget”. About 2 years ago, we started moving towards .Net standard, and last year published (internally) a large set of .Net standard 2.0 DLLs. Then: We realized that out “Framework” apps needed features outside of the standard, and had to make a special multi-target build system for “Framework 4.7.x” and “Standard 2.0”. Then: .Net standard 2.1 came alone, with “no support for .Net Framework” and we abandoned .Net standard, simplifying (we hope) to “Just one build” in .Net core 3.0. We cannot see any potential value in .Net standard 2.1 as “It is not quite .Net core 3.0” and “it cannot be used by our(legacy) Framework apps”.  We have a hard enough time getting communications to work between “Stable Framework Products” and new “Core 3.0 products” because MS nicely abandoned the “fairly new WCF” that we were expecing to use to connect the systems. We also have much remoting code. (We keep code over 10 years, so WFC had not yet completed our rollout when it was dropped!). Given that, trying to also support other build targets (such as .Net standard 2.x) was ruled out.

      • Avatar
        Andrew Witte

        Unless I missunderstud the goals of .NET 5 it would seem there will still be two runtimes. .NET Core and Mono so .NET Standard is still very relevent even in .NET 5. Also don’t forget about Unity3D + IL2CPP which is now focused on .NET Standard.

    • Avatar
      Immo Landwerth

      If you need to target .NET Framework, then .NET Standard 2.1 isn’t for you. However, it’s still useful for a library author in that you can multi-target for .NET Standard 2.0 and 2.1 and offer .NET Core/Xamarin/Unity customers more features while still making your library accessible to .NET Framework customers without having to target specific .NET implementations.

      • Avatar
        Scott Holodak

        As a library author, supporting both netstandard 2.0 and 2.1 sounds painful.  Embrace IAsyncEnumerable, Span<T>, new C# language features… and then reimplement everything without those for the massive potential install base that’s trapped on netfx due to a lack of a non-rewrite migration path (wcf, webforms, etc.).  It sounds like library authors will have a choice: embrace the PCL lifestyle that netstandard was supposed to replace & add compiler directives & csproj conditions, avoid 2.1 & c# 8 features like the plague, or drop support for netfx entirely and face the wrath of users who depended on it from framework-era code. I’m sure the last option will be great for core-era adoption charts in 3 years, but I think it will also cause a lot of legacy application rewrites/modernization efforts to happen on another tech stack. I get that resources are finite but it was a mistake to not support c# 8 and netstandard 2.1 in a new .net framework point release at this point in time, IMO.

        • Jay Tuley
          Jay Tuley

          They neededto make a C# 7.8 that had most of the compile time level features of C# 8, with none of the runtime features, then you could have a c# 7.8-.net std 2.0 and c# 8-.net std2.1 multi-target situation that could be worth while.

        • Avatar
          Gavin Williams

          Where should they draw the line then? .Net Framework was put on notice back in 2012 when the early version of UWP/WinRT was released (.net core being a part of that). We are coming up to 8 years orientation. Framework dev’s have to move forward sometime because the .net platform is terribly fragmented now. At least for productivity, office, social apps and games the excuse for staying with .net framework is getting a bit long in the tooth.

      • Avatar
        Daniel Sturm

        So basically the idea behind netstandard2.1 is to provide libraries for Xamarin/Unity. Makes sense, but given that very specific market I assume most libraries will either target netstandard2.0 or simply netcoreapp3.0 going forward. 
        That’s certainly what we’re planning to do as well. The additional effort simply isn’t worth for that small audience that might profit from it. 
        I’m wondering why you’re ignoring netstandard1.3 in your statistics, while certainly a minority (which admittedly is a good reason to ignore it) there are libraries that don’t need more features than available in it, so why target 2.0 if 1.3 is enough? 

        • Avatar
          Hall, Trevor

          Scott & Daniel, I agree generally with both comments, and have a very similar experience from users, and internal requirements (moving from netstandard 2.0 to core 3.0). Even though we are “mostly internal”, we do offer some tools directly to customers (though not via Github etc.). Since we sell a lot of “Windows products” most users want tools for Windows, but a growing % want Linux. I have no record of any of our customers wanting support for Xamrin or Unity. That makes it clear to us that all we need is “core 3.0” and eventually “.Net 5”. Other frameworks seem like a dead end. A lot of investment for very little gain. Also: Our devs want to use “The lastest features”. As per “scott” not supporting C#8 or netstandard 2.1 has “shut down” any future plans we had for framework anyway.

          • Avatar
            Ben Hall

            @scott and @trevor I suppose that’s kind of the point that I’m not doing very well at making here https://github.com/dotnet/corefx/issues/40039, partly because I get the impression that some C# 8 features will be usable in Standard 2.0 applications (particularly as we can right now in VS2019) but it is just not clear. Certainly early commentary on the subject said that we would see those not requiring runtime changes and then later get package as with Span<T>.

      • Avatar
        Gavin Williams

        UWP also relies on .net standard as it’s an easy target for library makers. In game dev and desktop app dev .net standard is the preferred approach. Libs that target UWP, .NetCore or .NetFramework in that space are not useful, because they close themselves off to general consumption..Net 5 will hopefully solve this problem for the rest of us.

  • Avatar
    Sergiy Korzh

    Does this research include unlisted packages as well? For example, some time ago, with a major update of our library, we assigned new IDs to the NuGet packages. New packages targets .NET Standard. Old packages target .NET Framework, and, most possibly, will never target .NET Standard. We will unlist those packages in some time, so, I think, it’d be better to exclude such unlisted packages from the observation.

  • Avatar
    Andrew Witte

    It would be interesting to see how this compairs to “.NET Core” / “.NET/Mono Framework” libs vs “.NET Standard” and what new projects are choosing.

  • Avatar
    Daniel Smith

    There’s quite a lot of confusion around targeting libraries to .NET Standard.  With hindsight, I think it would have made more sense to name it something like: “API Level 1”, “API Level 2”, etc similar to the approach Android uses, as this makes it clear that you’re targeting an API set rather than a specific framework version.

  • Avatar
    MgSam

    I think by next year this graph is going to go the other way- .NET Standard usage will start decreasing. As others have said, .NET Standard will largely be irrelevant when .NET 5 comes out. It’s already vastly less useful than it used to be given that .NET Framework will never implement 2.1+.
    And the lagging nature of the Standard has always made it far less useful than it could’ve been. I think in a few years we’ll look at it as another transitional, flawed experiment like PCL was.

    • Avatar
      Scott Holodak

      >>> .NET Standard will largely be irrelevant when .NET 5 comes out.
      I think you underestimate the volume of code that is not currently/easily portable to .NET Core.  netstandard2.0 will be the last & only version that can be targeted when attempting to modernize a framework-era codebase.  As dependent libraries target higher versions of the standard/netcore3.0/.NET 5 or C# >= 8.0, these applications will be stuck on library versions that are no longer actively maintained.  It will take a lot of effort in a lot of places to ensure that bugfixes/security updates make their way into the older version branches.

Leave a comment