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:
- Check
du -sh ~/Library/Caches/Yarnfor the Classic global cache and runyarn cache cleanfrom any Classic project (or globally) if it is large. - For Berry projects, check whether
.yarn/cacheis committed to git (git ls-files .yarn/cachereturns entries if it is). If it is not committed,yarn cache cleaninside the project is safe. - If it is committed (zero-installs), leave it alone — it is meant to be there.
- Walk any old projects for a
yarn-offline-mirroror 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.