Installing old .NET SDKs side by side with a Homebrew tap
dotnet-sdk versions HomeBrew Tap
At a glance
- What is it?
- homebrew-dotnet-sdk-versions is a Homebrew tap that publishes casks for individual .NET SDK versions so more than one can be installed at a time, plus meta versions that follow the newest patch of a major line. It solves a packaging problem, and it inherits the shared dependency behaviour of the official cask, including one destructive edge case around SDK 5.
- Who is it for?
- Use this tap if your CI matrix or a local project pins a .NET SDK that the official cask has already moved past, and check the dotnet-sdk5 entries in the README before touching that line, since installing SDK 5 removes the other SDKs on the machine. Skip it if you only need the current release or if you install the SDK through a version manager rather than Homebrew.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The official cask only carries the current SDK
The problem this tap solves is stated in one sentence at the top of the README. It contains different versions that you can install in parallel to the latest version provided by the official cask, which is the dotnet-sdk cask maintained in the homebrew-cask repository.
The official cask is a moving target by design. It tracks the current .NET SDK release, so a machine that installs it gets the latest version and nothing else through that path. Teams that need to build against an older SDK, or that need several SDK generations on one machine at the same time, end up outside what that single cask can express.
This tap fills that gap by publishing one cask per concrete SDK version. The version identifiers are systematic: dotnet-sdk10-0-400 for 10.0.402, dotnet-sdk8-0-100 for 8.0.132, and so on, with the pattern covering every release line from 2.1 through 10 in the tables.
Who it is for is specific. A developer with a global.json that pins an older target, or a CI system that has to prove a build works on more than one SDK generation, needs more than one SDK present on the same machine. That is the gap this repository fills, and it fills it entirely through Homebrew's own cask mechanism rather than through a new installer.
Meta versions track the newest patch of a major line
Alongside the pinned versions, the tap publishes meta versions. The README lists dotnet-sdk10 mapping to .NET SDK 10.0.203, dotnet-sdk9 to 9.0.319, dotnet-sdk8 to 8.0.426, down through dotnet-sdk2 for 2.2.402.
The behaviour is defined by a note under the table. These meta-packages install the latest MINOR and PATCH versions from the existing versions list below. So a meta cask is not a separate download. It is a pointer to whichever entry in the pinned table currently holds the highest minor and patch number for that major line.
That distinction matters for reproducibility. A pinned cask such as dotnet-sdk8-0-100 will install 8.0.132 every time, while the meta cask dotnet-sdk8 will install 8.0.426 today and would follow the table to a newer 8.0.x patch if the table is updated. The same applies to the preview lines: dotnet-sdk11-preview maps to 11.0.100-rc.2.26504.105, and the preview table covers 7 through 11.
The repository layout backs this up. There are Casks/ directory entries along with a meta-cask.rb.template and a meta-cask.x64.rb.template, and an auto_meta_updater.py script at the top level, which is how the meta packages stay pointed at the newest patch without every line being written by hand.
Tapping the repository and installing one version
The install path is three commands, and the third one is the check that tells you it worked.
brew tap isen-ng/dotnet-sdk-versions
brew install --cask <version>
dotnet --list-sdksThe first command registers the tap under the isen-ng/dotnet-sdk-versions name. The second installs one cask from it, where the version argument is a cask identifier such as dotnet-sdk8-0-400 or one of the meta names. The third lists the SDKs the dotnet host now sees, and it should show the version you just installed alongside any others already present.
The cask names are the identifiers listed in the tables, not the raw .NET version numbers. A reader coming from a Microsoft install script, where versions are written as 8.0.402, has to translate into dotnet-sdk8-0-400 first. That translation is the only friction in the flow.
Architecture is per cask rather than global. Every entry in the 6, 7, 8, 9 and 10 lines lists x64 & arm64, while the 2.x, 3.x and 5.0 lines are x64 only. The README points at that column for each version, and the x64-only rows carry the remark that on arm64 you should use dotnetx64 instead.
Installing SDK 5 removes every other SDK on the machine
This is the sharp edge in the tap and the documentation states it without hedging. Installing .NET SDK 5 using this tap or the official package from Microsoft will uninstall all other .NET SDKs on your machine. The workaround given is that you have to re-install the SDK versions you want from this tap after installing or upgrading to .NET SDK 5.
That behaviour is not unique to the tap. The same note covers the official package from Microsoft, which tells you the root cause sits in how the .NET 5 installer treats shared components rather than in how these casks are written. Either way, for anyone with a multi-version setup, the sequence matters: the SDK 5 install is not additive, and the other versions have to be put back afterwards.
The older entries make this worse rather than better. dotnet-sdk5-0-400 and dotnet-sdk5-0-200 are both x64 only, so on an arm64 Mac the documented path is to use dotnetx64, which means accepting a different executable and a different set of behaviours for that line.
If your workflow depends on several SDK generations being present, treat any operation involving SDK 5 as a full re-provisioning step rather than an incremental install.
Uninstalling needs zap because the dependencies are shared
Uninstalling is where the parallel-install design shows its cost. The README explains that the .NET SDK packages use shared dependencies between different versions, and that it is unwise to delete those dependencies when uninstalling a particular version, since it will cause other versions not to work anymore.
So a plain uninstall leaves the shared pieces in place, which is the correct behaviour for a multi-version machine and the wrong behaviour if you were expecting a clean removal. When there is a need to purge these dependencies, the documentation points at the zap flag.
brew uninstall --zap --cask <version>The warning that follows is the part to internalise. Uninstalling the official version will also remove these dependencies, so you will need to reinstall the particular version you want to use again. In other words, zap is safe for a machine where you are tearing everything down, and destructive for a machine where other SDK versions are still in use.
The same shared dependency structure means the order of operations on a shared CI image matters. Uninstalling the official cask and then expecting the tapped versions to still work is not a safe sequence.
Manual uninstalls leave Homebrew's bookkeeping wrong
The known issues section describes a state that is annoying to diagnose because Homebrew still believes the cask is installed. If your dotnet-sdk was installed using Homebrew but uninstalled manually outside of Homebrew, Homebrew will think that your dotnet-sdk is still installed. The README calls this unavoidable.
The symptom is a cask that Homebrew reports as installed while the files are gone, so a reinstall appears to do nothing. The README gives the example brew reinstall dotnet-sdk-8-400. The fix given is to zap the installation first, brew uninstall --zap dotnet-sdk-8-400, and then install it again.
A second known issue concerns upgrading the official dotnet-sdk cask, especially on a major version, and the description is cut off in the documentation as it stands. That entry is worth reading in full on the repository itself before upgrading the official cask on a machine that also carries tapped versions, because the interaction between the two sources of the SDK is exactly where the shared dependency problem shows up.
For most people the cleanest answer is to avoid the situation: keep every SDK version you need in the same source, either all from the official cask or all from this tap.
Ruby scripts keep the tap tables in sync automatically
The repository is small and mostly automation. Alongside the Casks directory, the top level holds auto_updater.py, auto_meta_updater.py, a brew_install_necessary.sh helper, and two deprecated shell scripts, auto_updater.deprecated.sh and auto_committer.deprecated.sh. The deprecation of the shell versions in favour of the Python ones shows the project migrating its tooling.
Continuous integration is visible from the badge links in the README, which point at three workflows in the repository: ci.yml, auto-updater.yml and auto-commit.yml. The naming matches the scripts, with one workflow validating the tap and two others keeping the casks and commits current.
Maintenance is active. The last push was on 2026-10-16 and the repository is not archived. The licence is MIT, with a LICENSE file at the root, and the primary language of the repository is Ruby, consistent with Homebrew cask definitions being Ruby. The repository has no GitHub releases, so there is no tag history to consult; the README tables and the META.md file are the record of what the tap currently contains.
That means the README, not a release feed, is the source of truth you check before planning an install. It is also why the auto-generated nature of the tables matters: a cask identifier you read about last month may now resolve to a different patch number through its meta package.
Editorial conclusion
Use this tap if your CI matrix or a local project pins a .NET SDK that the official cask has already moved past, and check the dotnet-sdk5 entries in the README before touching that line, since installing SDK 5 removes the other SDKs on the machine. Skip it if you only need the current release or if you install the SDK through a version manager rather than Homebrew. Before using it, run dotnet --list-sdks after the install to confirm the expected SDK versions are present, since the tap has no GitHub releases and only the README tables document what each cask contains.
Frequently asked questions
How do I install a specific .NET SDK version with homebrew-dotnet-sdk-versions?
Run brew tap isen-ng/dotnet-sdk-versions, then brew install --cask with a version identifier such as dotnet-sdk8-0-400 or a meta name such as dotnet-sdk8. Confirm the result with dotnet --list-sdks.
What is the difference between a meta version and a pinned version in this tap?
The pinned entries such as dotnet-sdk8-0-100 always install that exact SDK version, while the meta packages such as dotnet-sdk8 install the latest MINOR and PATCH versions from the existing versions list.
Does installing .NET SDK 5 from this tap remove my other SDKs?
Yes. The README states that installing .NET SDK 5 using this tap or the official package from Microsoft will uninstall all other .NET SDKs on your machine, and that you need to re-install the versions you want from the tap afterwards.
How do I completely remove a .NET SDK cask from this tap?
Use brew uninstall --zap --cask with the version, since the SDK packages share dependencies between versions. Note that zapping also removes the shared dependencies, so any other SDK versions still in use will need to be reinstalled.
Which architectures does this tap support?
The .NET 6, 7, 8, 9 and 10 entries list x64 & arm64, while the 2.x, 3.x and 5.0 entries are x64 only, with a remark that on arm64 you should use dotnetx64 for those.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/isen-ng-homebrew-dotnet-sdk-versions)Was this useful?