If you have used Yarn for more than a couple of years, there is a decent chance you are running two different tools that happen to share a name. Yarn Classic (version 1) and Yarn Berry (versions 2 through 4) cache packages in different places, in different formats, for different reasons, and cleaning one the way you would clean the other can either do nothing or delete something you actually wanted to keep. Here is what each one stores on macOS, and how to clear it safely.

How to tell which Yarn you are running

Run yarn --version inside a project. Anything starting with 1. is Classic. Anything 2.x, 3.x, or 4.x is Berry, and a Berry project almost always has a .yarnrc.yml file and a packageManager field in package.json pinning the exact version. The two behave differently enough that it is worth checking before you run any cleanup command.

Yarn Classic's cache

Yarn Classic keeps its global package cache at ~/Library/Caches/Yarn on macOS. Inside, packages are stored by name and version, similar in spirit to npm's cache but with Yarn's own layout. Every yarn install that needs a package not already cached downloads it once and stores it here; subsequent installs across any project on the machine reuse the same copy.

Clear it with:

yarn cache clean

This removes the entire global cache. The next yarn install in any project re-downloads what it needs. It is safe to run any time you are not mid-install, and it is the right first step if du -sh ~/Library/Caches/Yarn shows a number that surprises you — multi-gigabyte caches are common on machines that have built many projects with many dependency versions over time.

You can scope the clean to a single package:

yarn cache clean lodash

Useful if you suspect one specific cached tarball is corrupted rather than wanting to nuke everything.

Yarn Berry's cache is a different animal

Yarn Berry (2+) stores its cache differently, and by default it stores it inside the project, not globally. Per the topic brief for this cache family, Berry's package cache lives under ~/.yarn/berry/cache when a global cache is in play, and the project-local equivalent is a .yarn/cache folder sitting next to your package.json. Each entry is a zip archive of one package version, named with a hash so identical versions across projects are not re-fetched.

The command to clear it is the same verb, different scope:

yarn cache clean

Run inside a Berry project, this clears that project's resolved cache entries (or the shared cache, depending on your .yarnrc.yml settings). Because Berry defaults to storing the cache per-project rather than in one shared global folder, clearing it in one repository does not affect any other repository — which is the opposite of how Classic behaves.

Why deleting .yarn/cache in a zero-installs repo is a mistake

This is the detail that catches people out. Yarn Berry supports a workflow called zero-installs, where the .yarn/cache directory (holding the zipped packages) is committed to the git repository itself, along with a .pnp.cjs file that maps import paths straight to those zips. The entire point is that cloning the repo and running the code needs no yarn install step at all — the dependencies are already sitting in git history, checked out with everything else.

If a project has zero-installs enabled, .yarn/cache is not a disposable cache in the everyday sense — it is checked-in data that other developers and your CI pipeline depend on being present and correct. Look for a .gitignore that explicitly does not exclude .yarn/cache, or a mention of zero-installs in the project's README, before running any cleanup command inside such a repository. Deleting it locally is recoverable (git checkout brings it back), but deleting it and committing that deletion is not something you want to do by accident.

For projects that are not using zero-installs, .yarn/cache is excluded from git as normal, and clearing it behaves exactly like clearing any other build cache.

Offline mirrors in Yarn Classic

Before Berry existed, Yarn Classic offered a similar idea called an offline mirror. Setting yarn-offline-mirror ./npm-packages-offline-cache in a project's .yarnrc tells Yarn to copy every downloaded tarball into that folder and commit it to source control, so a machine with no network access can still yarn install. It solves the same problem zero-installs solves for Berry, with a plainer mechanism: a folder of .tgz files rather than a virtual filesystem.

If you inherit an older project with an offline mirror configured, treat that folder the same way you would treat a zero-installs cache: check whether it is committed before deleting it.

A safe cleanup routine

For a Mac that has accumulated years of Yarn usage across both major versions:

  1. Check du -sh ~/Library/Caches/Yarn for the Classic global cache and run yarn cache clean from any Classic project (or globally) if it is large.
  2. For Berry projects, check whether .yarn/cache is committed to git (git ls-files .yarn/cache returns entries if it is). If it is not committed, yarn cache clean inside the project is safe.
  3. If it is committed (zero-installs), leave it alone — it is meant to be there.
  4. Walk any old projects for a yarn-offline-mirror or similar offline cache folder configured in .yarnrc, and apply the same check before deleting.

None of this touches node_modules, which is a separate and usually much larger consumer of disk space in any JavaScript project regardless of which package manager wrote it.

Where VolumeLens fits in

Because Yarn's caching model changed shape between Classic and Berry, and because some of what looks like a disposable cache is actually committed project data, it is easy to either under-clean or over-clean by hand. VolumeLens scans your whole Mac and draws every folder to scale, so a multi-gigabyte ~/Library/Caches/Yarn shows up next to everything else competing for space — no guessing which folder is worth investigating. Insights, the paid tier, recognises common developer cache folders by name so you know what you are looking at before you touch anything.