If you are looking for Robocopy for Mac, the closest built-in answer is usually rsync. But the better question is not “what command has the same flags as Robocopy?” It is “how do I copy or mirror Mac developer folders without dragging node_modules, .git objects, virtual environments, caches, and build output into every backup?”
Robocopy for Mac: what developers actually need
Windows developers reach for Robocopy because it is practical. It can mirror a tree, copy only changed files, retry failures, preserve metadata, and run from scripts. macOS does not ship a command named robocopy, and a literal port is rarely the right goal. On a Mac, the usual equivalents are rsync, ditto, Finder copies, Git remotes, and dedicated folder sync apps.
For ordinary documents, almost any copy tool is fine. A development folder is different. It mixes files you authored with files your tools created. Source code, tests, migrations, docs, lockfiles, and configuration are worth backing up. Dependency trees, transpiler caches, coverage output, local virtual environments, and framework build directories are usually reproducible noise.
That split is why a Robocopy-style mirror can go wrong on macOS. If you mirror the whole project blindly, the destination looks complete but becomes heavy, slow, and noisy. If that destination is inside iCloud Drive, Dropbox, OneDrive, or Google Drive, the cloud client then tries to upload thousands of tiny generated files that it never needed to see.
The closest Robocopy equivalent on Mac is rsync
rsync is the tool most Mac developers should learn first. It compares a source and destination, copies changed files, preserves useful metadata with archive mode, deletes destination files when asked, and supports exclusion patterns. A basic Robocopy-style mirror looks like this:
rsync -avh --delete \
~/Developer/my-app/ /Volumes/DevBackup/my-app/
The trailing slash on ~/Developer/my-app/ matters. With the slash, rsync copies the contents of the folder into the destination. Without it, you may create an extra nested my-app directory. That detail feels small until a scheduled job has been running for a month.
For developer projects, start with a dry run and exclusions:
rsync -avhn --delete \
--exclude 'node_modules/' \
--exclude '.git/' \
--exclude '.venv/' \
--exclude 'venv/' \
--exclude 'vendor/bundle/' \
--exclude '.next/cache/' \
--exclude 'dist/' \
--exclude 'build/' \
--exclude 'coverage/' \
~/Developer/my-app/ /Volumes/DevBackup/my-app/
The n in -avhn is the dry-run flag. It tells you what would change without touching the destination. Remove it only after the output matches your intent. If you are replacing a Robocopy script, this dry-run habit is the closest thing to a seatbelt.
Robocopy vs rsync on Mac: the useful differences
Robocopy and rsync overlap, but they are not identical. Robocopy is Windows-native and deeply tied to NTFS behavior. rsync is Unix-native and common on macOS, Linux servers, and NAS devices. If your destination is another Mac, an external drive, a NAS share, or a server over SSH, rsync usually fits better than trying to bring Windows assumptions with you.
The biggest risk in both tools is destructive mirroring. Robocopy users know /MIR; rsync users know --delete. Both mean the destination should match the source, including removing files that no longer exist in the source. That is useful for a real mirror and dangerous when paths are wrong.
Before enabling delete behavior, verify three things: the source exists, the destination exists, and the dry-run output shows deletes you expect. Avoid running mirror commands with empty variables. Avoid running as root unless you have a narrow reason. Do not aim a delete-capable sync at the root of an external drive just because the path looked right in a script.
A safer Robocopy-style Mac workflow for code projects
1. Keep active projects out of cloud-synced folders
Use ~/Developer, ~/Code, or another local-only directory for projects you build and run. Cloud-synced Desktop and Documents folders are convenient for notes and PDFs; they are a poor default for active repositories. Every package install, test run, branch switch, and build can generate churn.
If you want a cloud copy, sync a filtered backup into the cloud folder. That gives iCloud or Dropbox a smaller, calmer tree: source files, docs, manifests, lockfiles, and configuration instead of dependency stores and build products.
2. Create a reusable exclude file
Instead of repeating exclusions in every command, put them in one file:
cat > ~/Developer/.sync-excludes <<'EOF'
node_modules/
.pnpm-store/
.yarn/cache/
.git/
.venv/
venv/
__pycache__/
.pytest_cache/
.mypy_cache/
vendor/bundle/
.next/cache/
.nuxt/
dist/
build/
coverage/
target/
.gradle/
tmp/
log/
.DS_Store
EOF
Then call rsync with --exclude-from:
rsync -avhn --delete \
--exclude-from="$HOME/Developer/.sync-excludes" \
~/Developer/my-app/ /Volumes/DevBackup/my-app/
Keep the file boring. A plain list is easier to audit than clever glob patterns. Add project-specific rules only when a project proves it needs them.
3. Decide what to do with .git
Excluding .git/ is often right for a clean working-tree copy, especially if the repository is pushed to GitHub, GitLab, or another remote. It keeps object churn and reflog noise out of the backup. But it is not universally right. If you have unpushed branches, local tags, hooks, or worktrees that matter, protect them separately.
A good pattern is layered: use Git remotes or mirror clones for history, and use folder sync for a clean copy of the working tree and adjacent project files. Do not ask one backup method to solve every recovery scenario.
4. Restore-test the result
After the first real copy, restore into a scratch folder and run the project’s setup command: npm ci, pnpm install --frozen-lockfile, pip install -r requirements.txt, bundle install, or whatever your stack expects. If the project rebuilds cleanly, your exclusions are probably safe. If it does not, adjust the rules before trusting the backup.
When ditto, Finder, or Unison fit better
ditto is a macOS-native copy command that preserves Mac file metadata well. It is useful for clean one-off copies, app bundles, and cases where resource forks matter. It is not as comfortable as rsync for dry-run-driven developer exclusions, so it is usually not the best Robocopy replacement for active code folders.
Finder is fine for manual copies of small, already-clean folders. It is weak for repeatable backups because it has no reliable exclusion policy, no dry run, no useful delete preview, and no logs. Copying a project and then deleting node_modules from the destination is a maintenance smell.
Unison can be useful for bidirectional synchronization when two locations both change. Treat that power carefully. Bidirectional sync is harder to reason about than one-way backup, especially with generated files. If you only need a clean copy from a source folder to a destination, one-way sync is simpler and safer.
Where LSyncer fits
If you enjoy maintaining shell scripts, rsync is still excellent. A reviewed script with a dry-run mode, an exclude file, and real logs is a serious tool. LSyncer is for the more ordinary developer problem: you want the Robocopy-style result, but you do not want another script to babysit.
LSyncer is a native macOS folder sync app for developer projects. It is built around the rules this article keeps coming back to: skip node_modules, .git, virtual environments, build output, and caches; run jobs on a schedule; and show whether a sync worked. It is local-first, with no cloud server in the middle, and it is a one-time $19.99 Mac App Store purchase.
That does not mean every Mac needs LSyncer. If the job is a one-off copy, use rsync. If the job is a recurring developer backup, an external SSD sync, a clean cloud handoff, or a local mirror that should never include generated junk, a dedicated filtered sync workflow is easier to keep honest.
Best practices for Robocopy-style Mac sync
- Preview first. Use
rsync -nor an app preview before delete-capable syncs. - Separate source from generated state. Back up source, tests, docs, manifests, lockfiles, and configuration. Rebuild dependencies.
- Use exclusions by default. Make
node_modules/, virtual environments, caches, and build folders opt-out of sync, not something you remember later. - Keep active code local. Put active projects outside iCloud Drive and sync filtered copies into cloud storage only when needed.
- Watch the last successful run. A backup that silently stopped running is not a backup workflow.
- Test restores. A clean destination is only valuable if the project can be rebuilt from it.
Related reading
- Best rsync alternative for Mac developers — a broader comparison of scripts, sync apps, and filtered folder workflows.
- Rsync GUI for Mac — what a visual sync workflow should expose before you trust it with code projects.
- Unison file sync Mac — when two-way sync is useful, and why generated folders need strict ignores.
- Mac copy folder exclude files — exact patterns for copying project folders without generated dependency junk.
- Copy only changed files on Mac — how to keep recurring backups incremental without copying caches every time.
FAQ
Is there a Robocopy for Mac?
macOS does not include Robocopy. The closest built-in equivalent for most developers is rsync, especially when used with --archive, --delete, --dry-run, and --exclude or --exclude-from rules.
What is the Mac equivalent of robocopy /MIR?
The closest rsync equivalent is rsync -av --delete source/ destination/. Use -n for a dry run first: rsync -avn --delete source/ destination/. Be careful because --delete removes destination files that are not present in the source.
Should I copy node_modules in a Mac project backup?
Usually no. Back up package.json and the lockfile, then recreate dependencies with npm ci, pnpm install --frozen-lockfile, or yarn install --immutable. Copying node_modules makes backups slower and can overload cloud sync clients.
Is ditto better than rsync on Mac?
ditto is useful for Mac-native copies and metadata preservation. rsync is usually better for Robocopy-style developer backups because it has dry runs, delete-based mirroring, and practical exclusion rules.
Can LSyncer replace a Robocopy script?
For local Mac developer folder sync, yes, when the goal is a repeatable filtered copy with schedules and visible status. It does not replace every server or SSH automation use case, but it is a good fit for recurring project backups that should skip generated folders.