A 256GB MacBook Air was never sized for software development, and macOS itself already claims 15–20GB of that before you install a single tool. Once you add Xcode, a couple of Docker images, and three or four active projects, you are running a professional workload on roughly 180GB of usable space — and every one of those tools was written by people who assumed you had more. This is not a guide to buying more storage. It's a guide to making 256GB work, because plenty of developers are stuck with exactly this machine and need a plan that survives contact with a real project.
Know what's actually claiming the disk
Before changing habits, look at where the space goes on a typical developer Air. The usual order of magnitude, largest first:
~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw— Docker Desktop's virtual disk, often 30–60GB even when idle~/Library/Developer/Xcode/DerivedDataandiOS DeviceSupport— 10–40GB combined if you touch Xcode at all- Per-project
node_modulesfolders — 200MB to 2GB each, and they multiply fast ~/Library/Developer/CoreSimulator/Devices— simulator disk images, several GB apiece- Package manager caches (
~/.npm,~/Library/Caches/Homebrew,~/.cargo) — individually modest, collectively significant
None of this shows up clearly in System Settings → Storage, which is why most 256GB owners genuinely don't know where their space went until they open a proper map of the disk.
Stop running Docker's VM disk locally when you can avoid it
Docker Desktop's Docker.raw file grows to accommodate whatever images and volumes you have pulled, and it does not shrink back down on its own — deleting containers does not shrink the underlying disk image. On a 256GB machine this single file is often the largest thing on the drive.
Three practical mitigations, in order of how much they help:
- Set a hard disk image size limit in Docker Desktop → Settings → Resources → Advanced, rather than leaving it unbounded.
- Run
docker system prune -a --volumeson a schedule, not just when the disk is full — pruning weekly keeps the image from creeping back up. - For work you don't need locally, use a remote or cloud dev container instead of pulling every image to your own disk. If your team already has a shared build server, point local work at it rather than duplicating multi-gigabyte images per laptop.
Choose pnpm over npm for anything with multiple projects
This is the single highest-leverage change for a JavaScript developer on a small disk. npm and Yarn Classic each install a full copy of every dependency into every project's node_modules. If you have six projects that all depend on react and typescript, you have six copies of each on disk.
pnpm instead keeps one content-addressable store — ~/Library/pnpm/store or ~/.local/share/pnpm/store — and hard-links or symlinks packages into each project. The dependency exists once on disk; every project's node_modules is mostly links, not copies.
| Package manager | 6-project footprint (rough) | Install speed |
|---|---|---|
| npm | 6× full node_modules | Slower on repeat installs |
| Yarn Classic | 6× full node_modules | Slower on repeat installs |
| pnpm | ~1× shared store + link overhead | Faster once the store is warm |
Switching an existing project is usually a rm -rf node_modules package-lock.json && pnpm import && pnpm install. It won't shrink a single-project machine much, but on a machine with five or more active repos the difference is real and compounds every time you clone something new.
Push large, cold data to the cloud deliberately
"Store in iCloud" from Storage → Recommendations works, but it applies a blanket rule to Desktop and Documents that can surprise you when a file you thought was local turns out to be a stub. A more deliberate approach for developers:
- Keep large binary assets (Sketch files, design exports, video, dataset dumps) in a shared drive or object storage rather than a git repo or local Documents folder.
- Archive finished projects:
ziportarthem, upload to cloud storage, and remove the localnode_modulesand build artefacts before archiving — no reason to compress dependencies you can reinstall. - For iOS DeviceSupport folders, delete support for iOS versions no device you own is running:
~/Library/Developer/Xcode/iOS DeviceSupportis safe to prune, and Xcode re-downloads what it needs the next time you attach that device.
An external SSD is not a compromise, it's the right architecture
A lot of developers treat an external drive as a stopgap for people who "should have bought more storage." In practice, an external SSD is often the better architecture even on a machine with more internal space, because it separates volatile, regenerable data from your system disk.
Good candidates to move to an external drive:
- Docker's data directory, if you relocate the Docker Desktop VM there
- Simulator devices you use occasionally but not daily
- Finished or paused projects you're not actively building
- Local database dumps and large test fixtures
A USB-C or Thunderbolt NVMe enclosure with a decent drive gives you near-internal speeds for sequential read/write, which is what most of this data needs. Keep your active project's git working copy on the internal SSD — file-system events and compiler I/O are latency-sensitive — and use the external drive for anything you open occasionally rather than continuously.
Build a rhythm, not a one-time cleanup
The mistake most 256GB owners make is treating cleanup as an emergency response to a full-disk warning. A short weekly routine avoids the emergency entirely: prune Docker, clear DerivedData if you've had a strange Xcode issue, check for node_modules folders in projects you haven't opened in a month, and glance at the size of your Downloads folder. Ten minutes a week is enough to keep a 256GB Air usable indefinitely.
Where VolumeLens fits
We built VolumeLens because a 256GB developer machine is exactly the case where guessing costs you real time — you need to know, in one look, whether it's Docker.raw, a forgotten node_modules, or three years of iOS DeviceSupport folders eating your build. It scans locally with no network code, flags the usual developer suspects by name, and only ever moves things to the Trash after you've reviewed the list. If you're rationing space on an Air, see how it maps a developer disk before you decide what to delete.