skipnothing/.NET Platform

What is .NET

Run `dotnet --info` on a dev machine and you get three sections back: a toolchain version, an executor version, and a list of executors installed. The same word, '.NET', is naming all three at once.

  • The same word, '.NET', covers three different on-disk things, each with its own version number. dotnet --info shows all three.
  • There's never a reason for a dev box to install both pieces separately, one of them already contains the other.
  • Even-numbered .NET releases get three years of patches, odd-numbered get two, the version number is a contract.
01

Three things ship as .NET

dotnet --info is the source of truth for what's installed under the word ".NET" on a machine. Run it on any developer box and three labeled sections come back:

.NET SDK:
 Version:           8.0.401

Host:
 Version:      8.0.7
 Architecture: x64

.NET SDKs installed:
 8.0.401 [/usr/share/dotnet/sdk]

.NET runtimes installed:
 Microsoft.NETCore.App 8.0.7 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
 Microsoft.AspNetCore.App 8.0.7 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]

Four sections, three different things. The first names the developer toolchain, the SDK: that contains the dotnet CLI, the C# compiler (Roslyn), MSBuild, and project templates. The second names the host runtime: what actually executes a built app. The fourth lists every runtime found on disk; one machine can hold many.

The runtime entries point at folder names: Microsoft.NETCore.App, Microsoft.AspNetCore.App. Those folders contain .dll files, collectively called the shared framework. Inside the shared framework lives the base class library (BCL): the System.* types every C# program already uses without thinking: string, List<T>, Task<T>, File. The BCL ships AS PART OF the runtime; it's not a separate install.

Three on-disk things, then: the SDK (toolchain), the runtime (executor + the shared framework with BCL inside), and, colloquially, the umbrella over both. One disambiguation while we're here: "modern .NET" (what dotnet new produces, cross-platform, the rebrand of .NET Core) is *not* the same product as ".NET Framework" (legacy, Windows-only, frozen at 4.8.1). The rest of this curriculum is about modern .NET.

WHAT `DOTNET --INFO` ACTUALLY SHOWS
02

SDK contains the runtime

What dotnet can do depends on what's installed. Three meaningful states:

Nothing installed. dotnet is not on PATH. Every command fails before it starts.

Runtime only. Install the .NET 8 runtime (a small download). dotnet --list-runtimes now shows Microsoft.NETCore.App 8.0.7. dotnet MyApp.dll runs an existing build. But dotnet build fails:

Could not execute because the specified command or file was not found.

The runtime download is missing the compilers, MSBuild, and templates. It can EXECUTE compiled output; it can't PRODUCE it.

SDK installed. Install the .NET 8 SDK (a larger download). dotnet build, dotnet new, dotnet publish, dotnet test, all work. And dotnet --list-runtimes now shows Microsoft.NETCore.App 8.0.7 because the SDK installer brought a matching runtime along automatically.

The relationship is one-way: the SDK contains a runtime; the runtime never contains an SDK. A developer box installs the SDK and gets the runtime for free. A deploy target installs only the runtime its app targets, saving install size, reducing attack surface, and removing the temptation to dotnet build on a production box.

The contains-relationship is the reason there's no fourth state called "SDK without runtime." It can't exist.

WHAT'S INSTALLED → WHAT `DOTNET` CAN DO
03

How SDK and runtime versions relate

In the dotnet --info output, the SDK and Host versions don't quite match. A common pairing:

.NET SDK Version:  8.0.401
Host Version:      8.0.7

Same major (8), same minor (0), different third segment. By design.

The .NET runtime follows MAJOR.MINOR.PATCH (rough SemVer). 8.0.7 = major 8, minor 0, patch 7, the patch bumps when a security or bug fix ships.

The .NET SDK uses a different scheme: X.Y.ABC where the last segment is two numbers packed into three digits. The first digit (A) is the SDK feature release. The last two (BC) are the SDK patch. So 8.0.401 means SDK feature release 4, patch 01, paired with .NET 8.

A worked sequence makes the rule click:

ChangeRuntimeSDKWhat changed
Initial release5.0.05.0.100Both ship
SDK patch only5.0.05.0.101SDK fix; runtime untouched
Both patched5.0.15.0.102Both fixed; SDK patch bumped
SDK feature5.0.15.0.200SDK adds features; jumps to 200
Runtime patch5.0.25.0.200Runtime fixed; SDK unchanged

The first two segments stay aligned because an SDK can only build apps for a runtime at or below its own major.minor. The third segment evolves on its own schedule. So SDK 8.0.401 paired with Host 8.0.7 is normal: the SDK has had four feature releases and one patch; the runtime has had seven patches. They ship together; they version separately.

ANATOMY OF A VERSION STRING

Keep going, sign up to unlock the rest

1 more part in this topic, plus 25+ more topics in .NET Platform.

Sign up, it's freeSee the full .NET Platform
The .NET Runtime0/5
#2 The CLR & Intermediate Language