Skip to content

Old SDKs, toolchains and version managers on a Mac

Old SDKs on a Mac pile up: nvm, pyenv, SDKMAN, rustup and Android Studio keep every version. Find what your projects use and remove the rest safely.

Developer storage · Published · 21 min read
A well-organized array of tools on a workshop pegboard wall.
Photo: Trudin Photography on Pexels

Old SDKs on a Mac pile up because developer tools keep every version side by side. nvm keeps each Node.js you install, pyenv each Python, rustup each Rust toolchain, SDKMAN each Java, and Android Studio each NDK. None removes an old version when you move to a new one.

Most can go. The ones to keep are your defaults and whatever a project still asks for, and projects say so in small version files such as .nvmrc, .python-version, .tool-versions, rust-toolchain.toml or global.json. Anything nothing points to is a version you'd only download again if you needed it.

Remove them the way they came. Many version managers are command-line tools with no app or menu, and their own uninstall removes one version cleanly. Where the catalog allows it, a version's folder can go to the Trash in Finder. Android's NDKs and SDK platforms come off in Android Studio, and simulator runtimes in Xcode.

What removing one costs is a download, sometimes a rebuild from source, and anything installed inside it, such as global npm packages or gems. Your projects' code is never touched.

Why old SDKs pile up on a Mac

Version managers exist so that one project can use Node.js 22 while another uses 24, without either noticing. To do that, each version is a complete install in its own folder. That's the feature, and it's also why the folders grow.

Why don't version managers clean up after themselves?

Because they can't know what you'll need. A project you haven't opened in a year may still ask for an old version, and removing it would break that project the next time you open it. So nearly every tool leaves removal to you.

There are exceptions. Gradle deletes copies of itself that no project has used for 30 days, and mise can remove versions none of your projects ask for, but only when you tell it to.

What's inside one version?

The runtime or compiler, its standard library, and anything installed into it. With nvm, packages you install globally with npm while using a version live inside that version's folder. With pyenv and rbenv, packages and gems do too. Remove the version and they go with it.

That's why two versions of the same tool can differ so much in size. On one Mac measured for this post, an old Node.js version was more than five times the size of a newer one, almost all of it global packages.

Versions side by side on one Mac
  • Node.js 22 with nvm, 11 global packages1,100 MB · Review first
  • Node.js 24 with nvm, 2 global packages200 MB · Review first
  • Python 3.11 from uv63 MB · Usually safe
  • Python 3.12 from uv56 MB · Usually safe

Measured in October 2026 on one Mac running macOS 27. The Node.js 22 folder held 954 MB of global npm packages. Your sizes depend on what you installed into each version.

How do you see them in Finder?

Most of these tools keep their versions in hidden folders in your home folder, whose names start with a period. Choose Go › Go to Folder, type a path from the table below, and press Return. Press Shift-Command-Period in a Finder window to show hidden files, and again to hide them.

To compare sizes, switch to list view and turn on Calculate all sizes in View › Show View Options. The post on showing folder sizes in Finder explains the options, and why Finder doesn't show them by default.

ToolWhere versions liveRemove a version withLevel
nvm~/.nvm/versions/nodenvm, or FinderReview first
pyenv~/.pyenv/versionspyenv, or FinderReview first
rbenv~/.rbenv/versionsruby-build's uninstall, or FinderReview first
uv~/.local/share/uv/pythonuv, or FinderUsually safe
asdf~/.asdf/installsasdf onlyReview first
mise~/.local/share/mise/installsmise onlyReview first
SDKMAN~/.sdkman/candidatesSDKMAN onlyReview first
rustup~/.rustup/toolchainsrustup onlyReview first

How to tell which versions your projects still use

Before removing anything, find out what's in use. It takes a few minutes, and it's the difference between a tidy-up and an afternoon of broken builds.

Which files pin a version?

Each tool reads a small text file in a project's folder, or in a folder above it, and uses the version named there. nvm, pyenv and uv all search the project folder and then each folder above it. The name tells you which tool it's for.

File in a projectRead byWhat it names
.nvmrcnvm, and mise when enabledA Node.js version
.python-versionpyenv and uvA Python version
.ruby-versionrbenvA Ruby version
.tool-versionsasdf and miseA version for each tool listed
mise.tomlmiseTool versions, among other settings
.sdkmanrcSDKMANJava and other JVM tool versions
rust-toolchain.tomlrustupA Rust toolchain
global.jsonThe .NET SDKAn SDK version and how far to roll forward

A few pins live in other files. Go projects can name a toolchain in go.mod, Android projects name an NDK with ndkVersion in a module's build file, and swiftly reads a .swift-version file. A project's own documentation often says which version it needs too.

How do you check a project's files without Terminal?

Open the project's folder in Finder and press Shift-Command-Period to show hidden files. Select a version file and press the Space bar to read it in Quick Look. Each holds a version number, often a single line.

Do this for each project you still work on. Note the versions, and you have the list to keep. A project you've finished and archived doesn't need its version installed; if you ever open it again, the tool can install that version then.

What's your default version?

Besides projects, each tool has a version it uses everywhere else, and that one should stay:

  • nvm uses the version with the alias default; its documentation says the first version you install becomes it.
  • pyenv keeps its global version in a file named version in ~/.pyenv, and rbenv in a file of the same name in ~/.rbenv.
  • asdf reads a .tool-versions file in your home folder, and mise its global settings in ~/.config/mise.
  • SDKMAN marks one version of each tool as the default, used by every new shell.

What else might point at a version?

Your editor may have a project set to a particular interpreter or SDK. Command-line tools you installed with pipx, uv or npm run on the version they were installed with. Scripts and scheduled jobs that name a full path to a runtime break when it goes.

Check these for anything you rely on daily. If something breaks after a removal, it's usually one of them, and the fix is to point it at a version you kept.

What's a sensible rule of thumb?

Keep your default, every version a current project pins, and the newest release of each line you use. Everything older in the same line, such as Node.js 20 next to 22 and 24, or three nightly Rust toolchains from last year, is a candidate.

Node.js, Python and Ruby: nvm, pyenv, rbenv and uv

These four keep each version as a plain folder, and the catalog allows moving one to the Trash in Finder. Each also has its own uninstall, which is the tidier route if you use the tool from the command line anyway.

nvm: Node.js versions and their global packages

nvm keeps each Node.js version in its own folder in ~/.nvm/versions/node, named after the version, such as v22.14.0. Its documentation describes nvm as a script for your shell, so it's command-line only, with no app or menu. Its own uninstall removes one version.

In Finder, move the folder for an old version to the Trash. The catalog rates Node.js versions installed with nvm as Review first, because the global packages installed for that version go with it.

Is it safe to delete an old nvm Node version?

Yes, if no project's .nvmrc asks for it and it isn't your default. If you remove the default, the catalog notes, node isn't available in new Terminal windows until you choose another.

Before removing it, look inside its lib/node_modules folder to see which global packages it holds. nvm has an option to reinstall global packages from one version into another, so tools you still use can move to a version you keep.

nvm also keeps the downloads it installed from in ~/.nvm/.cache. The nvm download cache is Safe: installed versions don't depend on it.

pyenv: Python versions built from source

pyenv keeps each Python in ~/.pyenv/versions. Its documentation says you can remove a version with its own uninstall, or simply delete the version's folder. The catalog rates Python versions installed with pyenv as Review first.

The cost is the rebuild: pyenv builds Python from source, so getting a version back takes a while. Environments made with the pyenv-virtualenv plug-in live inside the version and go with it. The post on old Python environments and versions goes through checking them.

rbenv: Ruby versions and their gems

rbenv keeps each Ruby in ~/.rbenv/versions, and its documentation says to remove an old version by deleting its folder. The ruby-build plug-in adds an uninstall command that does the same. Gems you installed for that Ruby live inside its folder.

The catalog rates Ruby versions installed with rbenv as Review first: a project whose .ruby-version asks for it won't run until Ruby is built again. The post on Ruby gems and rbenv versions covers gems in more depth.

uv: Pythons downloaded on demand

uv keeps the Pythons it downloads in ~/.local/share/uv/python, one folder per version. Its documentation says it downloads a version automatically when a project needs one that isn't installed, so a version you remove usually comes back when it's needed.

That makes Python versions installed by uv Usually safe rather than Review. What doesn't come back by itself is what was built on it: virtual environments and tools made with a removed version stop working until they're created again.

Black and white image of a complete toolset in an open box.
Version managers keep every size of tool you've ever used, in case a project asks for it again. Photo: Artem Podrez on Pexels

Multi-language managers: asdf and mise

asdf and mise manage many languages at once, Node.js, Python, Ruby, Go, Erlang and more, each version in its own folder. The catalog leaves their versions to the tools, because each keeps its own records of what it installed.

asdf: versions in .tool-versions

asdf installs each version in ~/.asdf/installs, in a folder for each tool and version. Projects name their versions in a .tool-versions file, one tool per line, and asdf's documentation says the file applies in its folder and every folder inside it.

asdf can also read files such as .ruby-version, but only if you turn that setting on; by default it reads only .tool-versions. It has a command that lists each tool's active version and the file that set it, which shows at a glance what a project uses.

How do you remove asdf versions?

With asdf. It's command-line only, and its uninstall removes one version of one tool at a time. The catalog rates asdf tool versions as Review first and leaves removal to asdf, which also maintains the small launcher programs it calls shims.

mise: versions, and pruning the unused ones

mise installs each version in ~/.local/share/mise/installs, such as installs/node/24.0.0. Projects name versions in mise.toml or .tool-versions. mise can read files other tools use, such as .nvmrc and .python-version, once you enable that for a tool.

mise remembers each settings file it has loaded. Its prune command removes installed versions that none of those files select, and its documentation describes a dry run that shows what would go without changing anything. That's the closest any of these tools comes to cleaning up for you.

Is mise's prune safe?

Mostly, with one blind spot. It only knows the settings files it has loaded, so a project you've cloned but never used with mise doesn't protect its versions. Since mise installs a missing version when a project asks for it, the cost is a download.

The catalog rates mise tool versions as Review first. mise's cache is separate: the mise cache holds lists of available versions and is Safe.

Java and the JVM: SDKMAN, Coursier and installed JDKs

Java is where versions multiply fastest: several JDKs from different vendors, plus versions of Gradle, Maven, Kotlin and Scala. Each tool that installs them keeps its own set.

SDKMAN: JDKs, Gradle, Maven and more

SDKMAN keeps each version in a folder for its tool, such as ~/.sdkman/candidates/java/21.0.4-tem, and marks one version of each tool as the default. A project can pin versions in a .sdkmanrc file, and SDKMAN can switch to them when you enter the folder, if you turn that on.

SDKMAN is command-line only. Its uninstall removes one version at a time, and its documentation warns against deleting its working folders by hand. The catalog rates SDKMAN candidates as Review first and leaves removal to SDKMAN.

What about JDKs you linked into SDKMAN?

SDKMAN can also list a JDK installed somewhere else as a local version. Its documentation notes that removing a local version from SDKMAN doesn't remove the installation itself. That JDK stays wherever it was installed, and comes off the way it was installed.

Coursier's Java versions

Coursier, used by Scala tools, installs Java versions in ~/Library/Caches/Coursier: in the arc folder in current versions, and the jvm folder in older ones. Despite the Caches location, these are installed Java versions, and Coursier's setup option can make one your default by editing your shell's settings files.

Coursier's documentation describes listing installed Java versions but not removing them. The catalog rates Java versions installed by Coursier as Review first and says to check which Java your shell and code editor use before removing one.

JDKs in /Library/Java/JavaVirtualMachines

JDKs installed from a vendor's installer go to /Library/Java/JavaVirtualMachines, one folder per version, such as jdk-25.jdk. Oracle's guide says several can be installed together, but only one per feature release: installing 25.0.1 replaces 25.

Oracle's uninstall is to remove that version's folder, which needs an administrator. In Finder, choose Go › Go to Folder, enter the path, and move the old version's folder to the Trash with an administrator's password. Oracle warns never to remove the Java tools in /usr/bin, which belong to macOS.

Oracle's installer arrives as a package inside a disk image, and its guide says you can delete the disk image once the JDK is installed. The same reasoning applies to other installers; the post on DMG and PKG files after installing explains why.

Gradle and Maven wrapper versions

Projects that use the Gradle or Maven wrapper download the build tool's version they name. The catalog rates Gradle Wrapper distributions and Maven Wrapper distributions as Safe: each downloads again when a project needs it. Gradle removes versions unused for 30 days by itself; Maven's wrapper doesn't.

Kotlin/Native's compiler folder

Kotlin Multiplatform projects that build for iPhone or other native targets use Kotlin/Native, which downloads its components into ~/.konan and caches results there. The catalog rates Kotlin/Native compiler and dependencies as Safe: the next build creates it again from scratch, more slowly and with a network connection.

FolderWhat's in itHow it comes offLevel
~/Library/Developer/ToolchainsSwift toolchains from swift.org or swiftlyFinder, or swiftlyReview first
~/.konanKotlin/Native's compiler and componentsFinderSafe
~/Library/Caches/Coursier/arcJava versions Coursier installedCoursierReview first
~/Library/Android/sdk/ndkAndroid NDK versionsAndroid Studio's SDK ManagerUsually safe
~/go/pkg/modGo modules and downloaded toolchainsGo's own clean commandSafe
/Library/Java/JavaVirtualMachinesJDKs from vendors' installersFinder, with an administratorNot in the catalog
/usr/local/share/dotnet/sdk.NET SDKsFinder, with an administratorNot in the catalog

Rust, Swift and Go toolchains

Compiled languages keep whole toolchains, not just runtimes: the compiler, the standard library for each platform, and tools such as formatters and language servers.

rustup: stable, nightly and pinned toolchains

rustup keeps each toolchain in its own folder in ~/.rustup/toolchains: stable, nightly, and specific versions a project asked for. Older nightly and pinned toolchains stay until you uninstall them, so a few months of trying nightly features can leave several behind.

A project pins its toolchain in a rust-toolchain.toml file, or the older rust-toolchain. rustup's documentation adds directory overrides, set with rustup itself rather than a file in the project, so a folder can be pinned with no file to show for it.

Is it safe to remove a Rust toolchain?

Usually. According to the catalog, by default rustup installs a project's toolchain again when it's missing, the next time you build. What isn't restored are targets and components you added yourself, such as a target for building iPhone apps.

rustup is command-line only, and its own uninstall removes a toolchain. The catalog rates Rust toolchains as Review first and leaves removal to rustup, which keeps its own records of what's installed.

Swift toolchains from swift.org and swiftly

Swift's package installer puts each toolchain in ~/Library/Developer/Toolchains as a folder ending in .xctoolchain, and the catalog also looks in the same folder at the top of the disk, /Library/Developer/Toolchains. Xcode lists them in Xcode › Toolchains, and choosing the default there switches back to Xcode's own.

The catalog rates Swift toolchains as Review first and allows moving one to the Trash in Finder. The Swift inside Xcode isn't affected. Older development snapshots may not be available to download again, so keep one you still test against.

Toolchains you installed with swiftly can also come off with swiftly's uninstall, which its documentation describes for single releases, whole minor versions or every snapshot at once. Projects can share a preferred toolchain with swiftly in a .swift-version file.

Go's downloaded toolchains

Since Go added toolchain switching, a project's go.mod can name a newer toolchain, and Go downloads it when needed. Go's documentation says those toolchains are downloaded like any other module, and the catalog notes they land in the module cache at ~/go/pkg/mod.

Go never trims that folder by itself. The Go module cache is Safe, and Go makes its files read-only, so it's cleared with Go's own clean command. The post on Go's build and module caches explains both.

A busy military storage room filled with equipment and crates, labeled 'Cucina per 3 Ufficiali'.
Every toolchain is a complete set, kept on the shelf until you take it down. Photo: Erik Mclean on Pexels

Android NDKs, SDK platforms and system images

Android Studio installs everything through its SDK Manager, in ~/Library/Android/sdk, and keeps every version you've ever installed. It's also the place to remove them.

Why do NDK versions multiply?

Android's documentation says Android Studio installs every version of the NDK side by side in the ndk folder. A project can name one with ndkVersion in its module's build file; if it doesn't, the Android Gradle plugin uses the version it was tested with, which differs between plugin versions.

The catalog rates the Android NDK as Usually safe: a project that used a removed version can't build its native code until it's installed again. The older ndk-bundle folder holds a single NDK from earlier versions of Android Studio.

How do you remove old NDK versions?

  1. In Android Studio, choose Tools › SDK Manager.
  2. Click SDK Tools, and select Show Package Details.
  3. Under NDK (Side by side), clear the versions you no longer need.
  4. Click Apply, and confirm.

Android's documentation adds that if you remove the old ndk-bundle NDK, you should remove the ndk.dir line from your projects' local.properties files.

SDK platforms and build tools

The Android SDK holds a platform for each Android version you've installed, plus build tools, the emulator and platform tools. Android's documentation says you need at least one platform to compile, and recommends building against the latest. It rates Usually safe.

In the SDK Manager's SDK Platforms tab, clear the checkbox next to versions no project compiles against, and click Apply. Removals show a red X until you apply them.

Emulator system images

Each virtual device starts from a system image for one Android version and device type. The catalog rates Android emulator system images as Usually safe: virtual devices that use a removed image won't start until it's downloaded again. Remove them in the same SDK Platforms tab, with Show Package Details selected.

Extra Xcode versions and simulator runtimes

On a Mac used for Apple platforms, the largest old versions aren't in your home folder at all. They're whole copies of Xcode, and the simulator runtimes each version downloaded.

Extra copies of Xcode

Each copy of Xcode is a complete app, so a beta or an older version kept for one project is many gigabytes. Look in Applications for names such as Xcode-beta. Xcode and Android Studio show up among the apps taking the most space, and that's often the quickest win.

Remove a copy you no longer need by moving it to the Trash. The post on uninstalling Xcode completely explains what to keep when other copies stay.

Simulator runtimes

Each iOS, watchOS, tvOS and visionOS runtime is several gigabytes, and runtimes stay installed after you update Xcode. The catalog rates Simulator runtimes as Managed by macOS: macOS keeps them as protected disk images.

Apple's documentation says to choose Xcode › Settings, click Components, click the information button next to a runtime you no longer need, and click Delete. Xcode shows how much storage each component takes. The post on deleting old simulator runtimes covers devices too.

.NET SDKs

Microsoft's .NET installs each SDK and runtime version side by side, and like the others, keeps them all until you remove them.

Where do .NET SDKs live?

Microsoft's documentation says a .NET install on macOS generally goes in /usr/local/share/dotnet, with a folder for each SDK version in sdk and each runtime version in shared. It points owners of Apple silicon Macs to a separate page on the folders used there.

Microsoft also says that, in general, you only need the latest SDK and the latest patch of each runtime your apps require. Older ones are safe to remove unless an app has a specific reason to need them.

Which SDK does a project use?

The newest installed, unless the project has a global.json. Microsoft's documentation says that file names an SDK version and how far to roll forward if it's missing, and that .NET looks for it in the project's folder and each folder above it.

How do you remove an old .NET SDK?

Microsoft's manual method is to remove the versioned folders. In Finder, choose Go › Go to Folder, enter /usr/local/share/dotnet/sdk, and move an old version's folder to the Trash with an administrator's password. Microsoft also offers an uninstall tool, which is command-line only.

Don't remove the whole dotnet folder. Microsoft recommends against it, because it would also remove the global tools you installed. No catalog entry covers .NET's SDK folders yet, so this is a removal you do yourself.

A safe order for removing old SDKs, and mistakes to avoid

Done in this order, nothing you rely on breaks without warning, and everything you remove can still be put back until you empty the Trash.

Step by step

  1. List what you have, tool by tool, with the folders above and their sizes.
  2. Note your defaults and every version a current project pins.
  3. Check what's built on each candidate: global packages, command-line tools, editor settings.
  4. Remove the largest first, with the tool's own uninstall where the tool is command-line only, or in Finder where that's allowed.
  5. Open one project from each language the way you usually do, in your editor or its own app, and check it still builds and runs.
  6. Empty the Trash after a few days of normal work.

A worked example

The Mac measured above had Node.js 22.14 and 24.21 from nvm. Say its projects' .nvmrc files all name 24, and 24 is the default. Node.js 22 holds eleven global packages: reinstall the ones still in use under 24 with nvm's own option, then move 22's folder to the Trash, about 1.1 GB.

The same Mac had Python 3.11 and 3.12 from uv. If a command-line tool installed with uv runs on 3.11, keep 3.11. If nothing uses 3.12, it can go, though at 56 MB it's hardly worth chasing, and uv fetches it again when a project asks.

Mistakes to avoid

  • Deleting a whole manager's folder, such as ~/.nvm or ~/.sdkman, to remove one version. That removes the tool and every version, and leaves its lines in your shell's settings.
  • Removing your default. New Terminal windows then have no version of that language until you set another.
  • Deleting asdf, mise, SDKMAN or rustup folders in Finder. Those tools keep records the catalog defers to; use their own uninstall.
  • Touching anything in /usr/bin or the Command Line Tools. Those belong to macOS and Xcode.
  • Pasting cleanup commands from the web. They delete outright, skipping the Trash, and a wrong path can take a whole toolchain with it.

Does removing old SDKs make builds faster?

No. It frees space, nothing more. Builds use the version a project asks for, and the other versions sitting beside it don't slow anything down. Having free disk space helps with large builds and updates, but that's the only connection.

How do you keep versions from piling up again?

Make it part of upgrading: when you move a project to a new version, remove the old one if nothing else pins it. Tools reinstall what's missing when it's needed, so erring on the side of removal costs a download, not your work.

A short look every few months catches the rest. The post on tracking disk usage over time shows how to spot which folders grow, and the guide to disk space on a developer's Mac covers the caches and build folders around these versions.

How the app does it

Wombit explains each of these folders like everything else on the disk. Select one in the map or the list, and the inspector says what it is, how safe it is to remove and what removing it costs, from the catalog's entry. File names and paths never leave your Mac.

Cleanup lists them by level:

  • Kotlin/Native's folder, nvm's download cache, mise's cache, the Gradle and Maven wrappers' downloads and Go's module cache are Safe and start checked.
  • uv's Python versions and Android's system images are Usually safe and wait for your choice. The Android NDK and SDK are Usually safe too, explained with Android Studio's SDK Manager steps.
  • nvm, pyenv and rbenv versions and Swift toolchains are Review first and wait for your choice.
  • asdf, mise, SDKMAN, Coursier and rustup versions are Review first too, explained with the tool's own way to remove them. The app doesn't move them.
  • Simulator runtimes are Managed by macOS, left to Xcode's Components settings.

For mise's cache and Go's module cache, the app runs the tool's own command after the review sheet. What a command removes can't be put back, and the sheet says so.

What the app runs, after you review itPRO

mise cache clear
mise's cache of version lists and task results
go clean -modcache
Go's module cache, including downloaded toolchains
  • ~/.nvm/versions/node/*

    Node.js versions installed with nvm

    A version of Node.js installed with nvm, along with the global npm packages installed for it.

    Review first · Moves it to the Trash

  • ~/.pyenv/versions/*

    Python versions installed with pyenv

    A version of Python installed with pyenv, along with the packages installed into it.

    Review first · Moves it to the Trash

  • ~/.rbenv/versions/*

    Ruby versions installed with rbenv

    A version of Ruby installed with rbenv, along with the gems installed for it.

    Review first · Moves it to the Trash

  • ~/.local/share/uv/python/*

    Python versions installed by uv

    A version of Python uv downloaded, used by the projects, tools and environments uv manages.

    Usually safe · Moves it to the Trash

  • ~/.asdf/installs

    asdf tool versions

    Versions of languages and tools that asdf has installed through its plugins, one folder for each tool and version.

    Review first · Explained only: never removed

  • ~/.local/share/mise/installs

    mise tool versions

    Versions of Node.js, Python, Go and other tools that mise has installed, one folder for each tool and version.

    Review first · Explained only: never removed

  • ~/.sdkman/candidates

    SDKMAN candidates

    Java versions and other JVM tools, such as Gradle, Maven and Kotlin, that SDKMAN has installed.

    Review first · Explained only: never removed

  • ~/Library/Caches/Coursier/{jvm,arc}

    Java versions installed by Coursier

    Java versions that Coursier downloaded and installed, for Scala and Java tools that use them.

    Review first · Explained only: never removed

  • ~/.rustup/toolchains/*

    Rust toolchains

    Versions of the Rust compiler, Cargo and the standard library that rustup has installed, one folder for each toolchain.

    Review first · Explained only: never removed

  • ~/Library/Developer/Toolchains/*.xctoolchain

    Swift toolchains

    Swift compilers and tools you installed from swift.org or with swiftly, separate from the Swift that comes with Xcode.

    Review first · Moves it to the Trash

  • ~/.konan

    Kotlin/Native compiler and dependencies

    The Kotlin/Native compiler and the components it downloads when you build Kotlin Multiplatform projects for Apple platforms and other native targets.

    Safe · Moves it to the Trash

  • ~/Library/Android/sdk/{ndk,ndk-bundle}

    Android NDK

    Versions of the Android Native Development Kit, used to build the C and C++ code in Android apps.

    Usually safe · Explained only: the app shows you how

Folders no catalog entry explains, such as installed JDKs and .NET SDKs, are never offered for removal. Seeing all of this is free. Cleanup is PRO, one $4.99 payment with lifetime access, and every Pro tool's review is free to open.

Frequently asked questions

Is it safe to delete old Node.js versions from nvm?

Yes, if no project's .nvmrc asks for it and it isn't your default. Global npm packages installed for that version go with it, so reinstall the ones you use under a version you keep first. Then move the version's folder to the Trash, or use nvm's own uninstall.

How do I know which SDK version a project uses?

Look for a version file in the project's folder, such as .nvmrc, .python-version, .ruby-version, .tool-versions, rust-toolchain.toml or global.json. Press Shift-Command-Period in Finder to show these hidden files, and Quick Look one to read the version.

Can I delete Rust toolchains in Finder?

Use rustup's own uninstall instead, because rustup keeps its own records of what's installed. By default rustup installs a project's toolchain again when it's missing, but targets and components you added yourself aren't restored.

Where are old Java versions stored on a Mac?

It depends on what installed them. Vendors' installers use /Library/Java/JavaVirtualMachines, SDKMAN uses ~/.sdkman/candidates, and Coursier uses its folder in ~/Library/Caches/Coursier. Remove each with the tool that installed it, or for a vendor's JDK, its folder with an administrator's password, as Oracle describes.

How do I remove old Android NDK versions?

In Android Studio, choose Tools › SDK Manager, click SDK Tools, select Show Package Details, clear the NDK versions you don't need and click Apply. A project that names a removed version with ndkVersion can't build its native code until it's installed again.

Does mise remove versions I don't use?

Only when you ask. Its prune command removes versions that none of the settings files it has loaded select, and a dry run shows what would go first. Projects you've never used with mise aren't tracked, so their versions aren't protected.

Should I keep old simulator runtimes?

Only the ones you still test on. Delete the rest in Xcode › Settings › Components, with the information button and Delete. Runtimes stay installed after Xcode updates until you remove them.

Will removing old SDKs speed up my Mac?

No. It frees disk space, nothing more. Builds use the version a project asks for, and other versions beside it don't slow anything down.

Sources

  1. Downloading and installing additional Xcode components · Apple Developer
  2. Node Version Manager (nvm) · nvm
  3. Overrides · The rustup book
  4. Usage · SDKMAN!
  5. Install and configure the NDK and CMake · Android Developers
  6. Remove the .NET runtime and SDK · Microsoft Learn