Installing the SDK
Install the .NET 10 SDK, confirm it with dotnet --version, and understand why the SDK is not the same thing as the runtime.
dotnet --versionTwo different downloads carry the name .NET, and picking the wrong one wastes an afternoon.
The runtime can only run programs that someone has already compiled. The SDK, short for Software Development Kit, can compile them. The SDK also contains a copy of the runtime, so installing the SDK gives you both. On the machine you write code on, install the SDK. On a server that only has to run the finished program, the runtime alone is smaller and is often all that is installed on purpose.
Installing it
Open dotnet.microsoft.com/download, choose .NET 10, download the installer for your operating system and run it. On Linux the usual package managers also carry it. Installers place the dotnet command on your PATH, so a new terminal window can find it.
Confirming it
Open a terminal and type dotnet --version. It prints the version of the SDK that your commands will use, for example 10.0.100. Three related options help when something looks wrong: dotnet --list-sdks prints every SDK installed, dotnet --list-runtimes prints every runtime installed, and dotnet --info prints both plus details about the machine.
What trips people up
Several versions live side by side. Installing .NET 10 does not remove .NET 8, and that is intended. If a folder or any folder above it contains a global.json file, that file decides which SDK version dotnet uses, which is why dotnet --version can print different numbers in two different directories.
Example
// Save these two lines as check.cs anywhere, then run:
// dotnet check.cs
// Running a single .cs file with no project file is a .NET 10 feature,
// added in SDK 10.0.100 with C# 14. A .NET 9 SDK cannot do it.
Console.WriteLine("The SDK compiled this file.");
Console.WriteLine("The runtime then executed it.");
// Output:
// The SDK compiled this file.
// The runtime then executed it.When to use it
- Setting up a new laptop so you can build and run a .NET service on it.
- Pinning one SDK version so every developer and the build server compile identically.
- Choosing what goes into a production container image: the runtime, not the SDK.
- Working out why dotnet --version prints a different number in two folders.
More examples
Checking what is actually installed
Your patch numbers and paths will differ; the shape of the output will not. Run these three before you believe any report that the SDK is missing, because the most common cause is a second installation earlier on the PATH.
dotnet --version
# 10.0.100
dotnet --list-sdks
# 10.0.100 [/usr/local/share/dotnet/sdk]
dotnet --list-runtimes
# Microsoft.NETCore.App 10.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
# Everything at once, plus the machine details:
dotnet --infoPinning the SDK version for a repository
Save this as global.json beside your solution, or generate it with dotnet new globaljson --sdk-version 10.0.100. Every dotnet command run in that folder or below then uses the pinned SDK, so a developer with a newer SDK installed still builds the same way as the build server.
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}A machine that can run but not build
This is the layout you want in a container image, because the runtime image is far smaller than the SDK image. Recognising it also saves you from the confusing report that dotnet exists but dotnet build does not.
# A production server with only the ASP.NET Core runtime installed:
dotnet --list-runtimes
# Microsoft.AspNetCore.App 10.0.0 [...]
# Microsoft.NETCore.App 10.0.0 [...]
dotnet --list-sdks
# prints nothing: no SDK here
dotnet Shop.dll # works: the runtime starts a compiled assembly
dotnet build # fails: build is an SDK command and the SDK is absent
Discussion