Posted in:

I recently wanted to try out the preview of .NET Core 2.1, so that I could experiment a bit with the new Span<T> functionality, which is something I'm very excited about.

Which SDK do I need?

But when I visited the .NET homepage (found at the easy to remember, and navigated to the all downloads page, I must confess to being a little confused by the experience...


That's right, there's two 2.1 SDK's available. The one called 2.1.300-preview1 is the one I wanted - that's the SDK for the .NET Core 2.1 preview runtime. Confusingly the 2.1.103 SDK actually contains the 2.0 runtime (not 2.1)! There's a new versioning strategy going forwards that will make the relationship between runtime and SDK easier to understand, but before that, the runtime and SDK version numbers did not necessarily correspond.

Will bad things happen if I install a preview SDK?

So I've worked out that I need 2.1.300-preview1, but like many developers, I've been burned in the past by installing bad preview bits that mess up my development machine. So I had two key questions before I was ready to pull the trigger. First, will installing a preview .NET Core SDK break something?, and second, can I easily switch back to the release version of the SDK?

There's good news on both fronts. First of all, .NET Core SDKs are installed side by side, so will not modify any previous SDK installations. So when I install the preview, all that happens is that I get a new folder under C:\Program Files\dotnet\sdk. You can see here all the various .NET Core SDK versions I've got installed on this PC:


And the same is true for the .NET Core runtime. Inside the C:\Program Files\dotnet\shared\Microsoft.NETCore.App folder we can see all the versions of the runtime I've installed, including the 2.1.0 preview that came with the SDK:


So that's great, I've got the 2.1 preview SDK and runtime available on my machine, and I can experiment with it. But now we need to know how to identify which one of these SDKs is currently active, and how to switch between them.

What version of the SDK am I currently running?

If I go to a command line and type dotnet --version it will tell me the SDK version I'm currently running, which will be the preview version I just installed:


The way this works is that I'm actually calling dotnet.exe which resides in C:\Program Files\dotnet. That is just a proxy which passes on my command to whatever the latest SDK is, which by default will just be the folder in C:\Program Files\dotnet\sdk with the highest version number.

What SDK and runtime versions are installed?

Two other handy commands to know are dotnet --list-sdks to see all installed SDKs:


and dotnet --list-runtimes to see all installed runtimes:


How can I switch between .NET Core SDK versions?

Since my current version is 2.1.300-preview1-008174, if I run dotnet new console it will create me a .csproj with that targets the .NET Core 2.1 runtime (which is of course still in preview at the time of writing):

<Project Sdk="Microsoft.NET.Sdk">

That's great if I want to experiment with the .NET Core 2.1 preview, but what if I just want to get back to the version I was using before, and build .NET Core 2.0 apps? In other words, when I type the dotnet command in the console, how can I control which version of the SDK I am actually using?

The answer is that we can easily switch between versions of the SDK by creating a global.json file. It simply needs to reside in the folder you're working in (or any parent folder). So if there is a global.json file in my current folder or any parent folder with the following contents, I'll be back to using the 2.1.103 version of the SDK (which if you remember targets the 2.0 runtime).

  "sdk": {
    "version": "2.1.103"

Having created this global.json file, running dotnet --version now returns 2.1.103:


And if I do a dotnet new console we'll see that the generated .csproj targets the 2.0 runtime, as we'd expect:

<Project Sdk="Microsoft.NET.Sdk">

Easily create a global.json file

One final tip - you can easily create a global.json file in the current working folder with the dotnet new globaljson command. This will create a global.json file and pre-populate it with the latest version of the SDK available. You can also control the version that gets written to the file with the --sdk-version argument. For example, dotnet new globaljson --sdk-version 2.0.2 generates the following global.json:

  "sdk": {
    "version": "2.0.2"


It's always daunting to install preview bits on your developer machine as you don't know what might break, but with .NET Core, SDKs and runtimes are installed side by side, and so long as you know about global.json it's very easy to control which version of the SDK you're using. And the version of the runtime can also be controlled using the TargetFramework (and, if necessary the RuntimeFrameworkVersion) properties in your .csproj file.


Comment by Kevin Long


Kevin Long
Comment by Nicholas Petersen

This seems crazy that they used the name `global.json` -- something which doesn't even have the name `dotnet` in it. I would argue they should change this to something like `global-dotnet.json`, ... or maybe just `dotnet.json`. Anyways, thanks for the write up, was helpful.

Nicholas Petersen
Comment by Travis Illig

These helpers that add `dotnet` commands for listing and changing SDK versions may be of use:

Travis Illig
Comment by Erich Brunner

Thanks a lot for that detailed explaination

Erich Brunner
Comment by Brad Cote

Excellent article - I spent a day uninstalling / repairing SDKs to get a previously running project to run again. I installed SDK 2.1.401 and rebroke my project, then added the global.json file with 2.1.202, did a Rebuild Solution and it is back up and running again.
Thank you!

Brad Cote
Comment by Emiliano Parizzi

I was expecting this to be something like "dotnet use [version]" like NVM for Node, but I guess we need to keep creating config files everywhere...

Emiliano Parizzi
Comment by Haugis

A little QOL tip; run dotnet --info to see your .NET versions - currently active, and all SDKs and runtimes.

Comment by Hayot Ismatov


Hayot Ismatov
Comment by zam

imagine if we have something like that

Comment by James Heffer

Thanks for the article man.

James Heffer
Comment by Mason Bailie

Thanks! This helped solve my problem.

Mason Bailie
Comment by Elton Alves

Great article man, it helped me alot. Thanks!

Elton Alves
Comment by Sergio Rodríguez

Thank you, Mark. Very useful!

Sergio Rodríguez