npm install slow Mac searches usually start after the same pattern: a project that installed quickly on a clean folder suddenly takes minutes, Finder starts lagging, and a sync process wakes up at the same time. On macOS, the bottleneck is often not npm itself. It is a watched folder — iCloud Drive, Dropbox, Google Drive, OneDrive, or a backup utility — trying to index and sync every tiny file that npm just created inside node_modules.
npm install slow Mac: why dependency installs punish sync tools
npm install is a file-system stress test. A medium Node.js project can create tens of thousands of files: package metadata, nested dependencies, binaries, type definitions, lockfile updates, cache reads, and postinstall output. Most files are small, but each one still produces file events, metadata changes, directory updates, and sometimes quarantine or permission checks on macOS.
That is fine when your project lives in a normal local folder such as ~/Developer/my-app. APFS can handle a burst of small files. The trouble starts when the project lives inside a folder watched by a cloud sync client. iCloud Drive does not see “a disposable dependency tree.” It sees thousands of new files that might need upload, deduplication, conflict checks, thumbnail/index work, and status badges in Finder.
This matters because the fix is different. Upgrading npm, changing registries, or clearing the package cache can help when network fetches are slow. They do almost nothing when the slow part is macOS and a sync client fighting over a rapidly changing dependency folder.
Quick diagnosis: is npm slow, or is macOS syncing too much?
Before changing your workflow, separate package-manager time from file-system sync time. Run the same install in a local-only folder and compare it with the watched folder.
# Make a local-only test area outside iCloud/Desktop/Documents
mkdir -p ~/Developer/npm-speed-test
cd ~/Developer/npm-speed-test
# Copy only the package manifests from the slow project
cp /path/to/slow-project/package.json .
cp /path/to/slow-project/package-lock.json . 2>/dev/null || true
time npm ci
If the local folder is dramatically faster, the package manager is probably not the primary bottleneck. Also check Activity Monitor while the slow install runs. Processes such as bird for iCloud Drive, Dropbox, Google Drive, OneDrive, fileproviderd, Spotlight, or antivirus/scanner tools showing sustained CPU or disk writes are a clue that the install is being amplified by watchers.
Common causes of a slow npm install on Mac
There are several real causes, and they can stack. The highest-leverage fix depends on which layer is slow.
npm or network causes
- Cold package cache after a clean machine setup.
- Private registry latency or authentication retries.
- Large native packages running postinstall scripts.
- Rosetta or architecture mismatches on Apple Silicon.
macOS folder causes
- Project stored inside iCloud Drive, Desktop, or Documents.
- Dropbox, Google Drive, or OneDrive watching the project.
- Spotlight or security tools scanning new dependency files.
- Backup tools copying
node_modulesduring the install.
Network problems usually show up as long pauses before packages download. Folder problems show up as local CPU, disk I/O, fans, and Finder lag while files are being written. If your lockfile is stable and the same command is fast in ~/Developer, focus on the folder.
package-lock.json.How to fix npm install slow Mac problems without breaking your workflow
1. Move active projects out of watched folders
The simplest fix is also the most reliable: keep active repositories in a local-only directory. A good default is ~/Developer, ~/Code, or another folder outside Desktop, Documents, iCloud Drive, Dropbox, Google Drive, and OneDrive.
mkdir -p ~/Developer
mv ~/Library/Mobile\ Documents/com~apple~CloudDocs/Projects/my-app ~/Developer/my-app
cd ~/Developer/my-app
npm ci
Do not drag a live project while npm, your editor, TypeScript, or a dev server is running. Stop background processes first, move the project, then reinstall dependencies if needed. If your editor has workspace-specific paths, reopen the project from the new location.
2. Sync source code, not generated dependencies
For backups, you usually need source files, configuration, lockfiles, scripts, and documentation. You do not need node_modules, .next, dist, coverage, .turbo, .cache, or temporary build output. Those folders are reproducible and noisy.
If you use rsync, make the exclusion list explicit and run a dry run before deleting anything at the destination:
rsync -avhn --delete \
--exclude node_modules \
--exclude .git \
--exclude .next \
--exclude dist \
--exclude coverage \
--exclude .turbo \
~/Developer/my-app/ /Volumes/Backup/my-app/
Remove the n from -avhn only after the preview looks right. For a deeper command-line workflow, see our rsync dry run on Mac guide and the rsync exclude node_modules on Mac checklist.
3. Use iCloud exclusion workarounds carefully
iCloud Drive does not offer a first-class “exclude this subfolder” UI. Some developers use .nosync markers or folder names that prevent iCloud from syncing a path. That can help for throwaway folders, but it is a workaround, not a clean policy system.
# Example for a folder you know should never sync
mkdir -p node_modules
touch node_modules/.nosync
The catch is maintenance. If you delete and recreate node_modules, the marker may disappear. If you create new projects, you must remember the rule again. If you want a broader iCloud-specific guide, read how to stop iCloud from syncing certain folders on Mac.
4. Check editor, Spotlight, and security scanners
Cloud sync is the common culprit, but it is not the only watcher. VS Code, JetBrains IDEs, Spotlight, backup agents, and endpoint security tools can all react to dependency bursts. Most developer editors already ignore node_modules for search, but project-specific settings are worth checking when a single repository behaves badly.
// .vscode/settings.json
{
"files.watcherExclude": {
"**/node_modules/**": true,
"**/.next/**": true,
"**/dist/**": true
},
"search.exclude": {
"**/node_modules": true,
"**/.next": true,
"**/dist": true
}
}
Do not use this as a substitute for fixing cloud sync. Editor excludes reduce editor work; they do not stop iCloud or Dropbox from seeing files in watched folders.
5. Prefer clean, repeatable installs
Use npm ci for CI-like repeatability when a lockfile exists. It removes the existing node_modules folder and installs exactly what the lockfile describes. That can feel slower than incremental npm install for tiny changes, but it makes debugging easier because you are not wondering whether a stale dependency tree caused the problem.
# Good for reproducible local verification
npm ci
# Good when intentionally adding or updating packages
npm install package-name
If native packages are slow, check whether you are using an Apple Silicon native Node build. Running x64 Node under Rosetta can add friction for packages that compile native modules.
Where Lsyncer fits in the npm install slow Mac workflow
If the real requirement is “my code should be backed up” rather than “every dependency file must be mirrored,” a filtered sync workflow is a better match than a cloud drive folder. Lsyncer is built around that idea: choose a source folder, choose a destination, and skip the generated folders that make developer projects painful to sync.
Out of the box, Lsyncer is designed for patterns such as node_modules, .git, virtual environments, build output, and caches. That means your active project can live in ~/Developer, npm can install without a cloud client chasing every file, and your meaningful source files can still be copied to a backup location on a schedule. It is a one-time $19.99 Mac app, not a subscription, and it stays local unless you choose a destination that syncs elsewhere.
That is not the only valid setup. A carefully maintained rsync script is excellent if you like scripts. Syncthing is strong if you want peer-to-peer sync and do not mind a web UI. The important shift is the same in every approach: stop treating generated dependency folders as precious data.
Best practices for faster Node.js projects on macOS
- Keep active repos outside watched cloud folders. Use
~/Developeror~/Codefor day-to-day work. - Commit lockfiles. A reliable
package-lock.json,pnpm-lock.yaml, oryarn.locklets dependencies be rebuilt instead of backed up. - Back up source, not dependency trees. Exclude
node_modules,.next,dist,coverage, and local caches. - Preview destructive syncs. Use dry runs before
--deletewithrsyncor any mirroring tool. - Watch Activity Monitor during one bad install. The process list often tells you whether npm, cloud sync, Spotlight, or a scanner is doing the work.
Related reading
- Why iCloud freezes your Mac when syncing node_modules — the iCloud-specific version of the same dependency-folder problem.
- How to sync node_modules without freezing your Mac — broader cloud-provider options and exclusion strategies.
- Backup Node.js project on Mac — a clean backup workflow that keeps source and lockfiles while skipping dependency junk.
- File sync for Mac developers — a practical comparison of Finder, rsync, iCloud, and filtered app workflows.
FAQ
Why is npm install slow on Mac but fast on another folder?
If the slow folder is inside iCloud Drive, Desktop, Documents, Dropbox, Google Drive, or OneDrive, the install may be triggering sync work for every file in node_modules. Test the same project in ~/Developer to separate npm performance from folder watcher overhead.
Should I back up node_modules?
Usually no. node_modules is generated from package.json and your lockfile. Back up the manifests and source code, then recreate dependencies with npm ci or your package manager of choice.
Does clearing the npm cache fix slow installs?
Sometimes, but only for cache corruption or stale package data. If Activity Monitor shows cloud sync or file-provider processes working hard during installation, clearing the npm cache will not address the main bottleneck.
Is pnpm or Yarn better for this problem?
They can reduce duplication and change dependency layout, especially pnpm, but they do not make watched cloud folders a good place for active dependency trees. Keep the project local and sync filtered source files regardless of package manager.
What is the safest backup workflow for Node.js projects on Mac?
Keep active projects in a local folder, commit source and lockfiles to Git, and use a filtered backup that excludes generated folders. Tools such as rsync, Syncthing, or Lsyncer can all work if the exclusion policy is clear.