When should we use one over the other?
The decision is a trade-off between compatibility and API access.
Use a .NET Standard library when you want to increase the number of applications that will be compatible with your library, and you are okay with a decrease in the .NET API surface area your library can access.
Use a .NET Core library when you want to increase the .NET API surface area your library can access, and you are okay with allowing only .NET Core applications to be compatible with your library.
For example, a library that targets .NET Standard 1.3 will be compatible with applications that target .NET Framework 4.6, .NET Core 1.0, Universal Windows Platform 10.0, and any other platform that supports .NET Standard 1.3. The library will not have access to some parts of the .NET API, though. For instance, the
Microsoft.NETCore.CoreCLR package is compatible with .NET Core, but not with .NET Standard.
What is the difference between Class Library (.NET Standard) and Class Library (.NET Core)?
Compatibility: Libraries that target .NET Standard will run on any .NET Standard compliant runtime, such as .NET Core, .NET Framework, Mono/Xamarin. On the other hand, libraries that target .NET Core can only run on the .NET Core runtime.
API Surface Area: .NET Standard libraries come with everything in
NETStandard.Library, whereas .NET Core libraries come with everything in
Microsoft.NETCore.App. The latter includes approximately 20 additional libraries, some of which we can add manually to our .NET Standard library (such as
System.Threading.Thread) and some of which are not compatible with the .NET Standard (such as
Also, .NET Core libraries specify a runtime and come with an application model. That’s important, for instance, to make unit test class libraries runnable.
Why do both exist?
Ignoring libraries for a moment, the reason that .NET Standard exists is for portability; it defines a set of APIs that .NET platforms agree to implement. Any platform that implements a .NET Standard is compatible with libraries that target that .NET Standard. One of those compatible platforms is .NET Core.
Coming back to libraries, the .NET Standard library templates exist to run on multiple runtimes (at the expense of API surface area). Conversely, the .NET Core library templates exist to access more API surface area (at the expense of compatibility) and to specify a platform against which to build an executable.
Here is an interactive matrix that shows which .NET Standard supports which .NET implementation(s) and how much API surface area is available.