●FUNDING — Rork closed a $15M seed round led by Left Lane Capital, with Peak XV, True Ventures, Goodwater, and a16z Speedrun●SCALE — In under a year, Rork became one of the world's largest AI mobile app building platforms by web traffic●MAX — Rork Max generates native Swift apps, powered by Claude Code and Claude Opus 4.6●NATIVE — Rork Max reaches Xcode-class territory: AR/LiDAR, Metal 3D, widgets, Live Activities, HealthKit, and Core ML●STACK — Standard Rork builds iOS and Android together in React Native (Expo), so non-engineers can ship real apps●PRICE — Plans start free, paid tiers from $25/month, and Rork Max at $200/month●FUNDING — Rork closed a $15M seed round led by Left Lane Capital, with Peak XV, True Ventures, Goodwater, and a16z Speedrun●SCALE — In under a year, Rork became one of the world's largest AI mobile app building platforms by web traffic●MAX — Rork Max generates native Swift apps, powered by Claude Code and Claude Opus 4.6●NATIVE — Rork Max reaches Xcode-class territory: AR/LiDAR, Metal 3D, widgets, Live Activities, HealthKit, and Core ML●STACK — Standard Rork builds iOS and Android together in React Native (Expo), so non-engineers can ship real apps●PRICE — Plans start free, paid tiers from $25/month, and Rork Max at $200/month
Cloud-Synced Folders Break App Builds — Excluding Build Artifacts From Sync to Fix It for Good
A project living in Dropbox or iCloud Drive stopped building one morning. The cause was sync creating conflicted copies inside build artifacts. Here is how I excluded node_modules and Pods from sync to stop the recurrence, told as an indie developer's field notes.
I noticed a file named "(Hirokawa's conflicted copy)" multiplying inside Pods on the morning a build stopped in red. The same header appeared twice and the linker was confused. This was a project that had built fine the night before.
The culprit was cloud sync. As an indie developer I keep source inside Dropbox and work across multiple machines, and that sync had reached all the way into build artifacts, cutting in mid-write to create "conflicted copies." Putting source in the cloud is not the problem. The pitfall was that I was also syncing artifacts that never needed to sync.
Plenty of developers run this same setup. Here is how I fixed the problem for good across the Dolice projects.
Why builds break inside a synced folder
A build generates, overwrites, and deletes a large number of files in a short window: expanding node_modules, installing Pods, the compiler's intermediates. While those are being written, the cloud sync client reacts to "detected changes" and starts uploading.
Two troubles arise here. One is that the same file receives different changes across machines or version history, the sync client cannot resolve it, and it creates a conflicted copy. The other is that sync temporarily locks or dematerializes a file into a placeholder, so the build tool cannot read the real contents it expected.
So what is broken is not the code but the state of the artifacts around the code. That is why "clean and rebuild" fixes it, yet it breaks again days later. In my setup, with artifacts left in sync, the recurrence rate was effectively 100%. As long as the cause is artifact sync, symptomatic fixes will not stop it.
Which directories to exclude from sync
The rule is simple: do not sync anything you can regenerate. Sync only source and config, and exclude everything a single command can rebuild.
Directory
What it is
How to regenerate
node_modules/
npm dependencies
npm install
ios/Pods/
CocoaPods dependencies
pod install
~/Library/Developer/Xcode/DerivedData/
Xcode intermediates
rebuilt on build
ios/build/ · android/build/
build output
rebuilt on build
.gradle/ · android/.gradle/
Gradle cache
rebuilt on build
.expo/ · .expo-shared/
Expo local cache
regenerated at start
*.xcworkspace/xcuserdata/ · .swiftpm/
user state / SPM workspace
unneeded / regenerated
Syncing .git is not fatal, but to avoid history conflicts I use GitHub as the remote separately from cloud sync and include .git itself in the exclusions. I recommend this arrangement.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦If your builds break intermittently inside a synced folder and you can't find the cause, you'll understand why it happens and stop it today with an exclusion setting
✦You'll get the list of artifacts to exclude from sync — node_modules, Pods, DerivedData — plus the exact exclusion steps for both Dropbox and iCloud
✦You'll be able to drop a reusable script into your own setup that excludes build artifacts from sync in one run at project creation
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Dropbox: exclude each folder with an extended attribute
Dropbox has an extended attribute that marks a folder as "do not sync." On macOS you set com.dropbox.ignored on the target folder with the xattr command. The steps are as follows.
Delete existing conflicted copies to clean up the state
Set the com.dropbox.ignored attribute on the target folder
Confirm the attribute is set with xattr -p
# Exclude the folder from Dropbox sync (macOS)# Setting the value to 1 keeps it locally but stops syncing itxattr -w com.dropbox.ignored 1 ios/Podsxattr -w com.dropbox.ignored 1 node_modules# Confirm it is set (a returned 1 means excluded)xattr -p com.dropbox.ignored node_modules# => 1
A note of caution: even after exclusion the folder stays local. The build works as before; it just stops uploading to the cloud. If conflicted copies are already scattered around, delete them first, then set the attribute for a clean result.
# Wipe existing conflicted copies before setting the exclusion attributefind . -name "*conflicted copy*" | while read f; do echo "removing: $f" rm -rf "$f"done
iCloud Drive: exclude by naming and relocation
iCloud Drive has no dedicated attribute like Dropbox. Instead there are two realistic ways to handle it.
One uses the convention that iCloud does not sync files or folders ending in .nosync. But renaming a folder makes the build tool lose its reference, so it is hard to apply to an artifact directory itself.
The other is reliable: place the working directory outside iCloud. Keep source in a non-synced location like ~/Developer/, and copy only the deliverables into iCloud when needed. In this case I choose to re-clone the whole repository into ~/Developer/. Rather than trying to pull artifacts out, it causes fewer accidents to never create them inside the synced area in the first place.
Stopping recurrence: one script to run at project creation
Excluding by hand once means forgetting the next time you create a project. I keep one small script to run at the end of every new setup, so artifacts are excluded mechanically.
#!/usr/bin/env bash# dropbox-ignore-build-artifacts.sh# Run at the project root to exclude regenerable directories from Dropbox sync.set -euo pipefail# Exclusion targets (list only what can be regenerated)TARGETS=( "node_modules" "ios/Pods" "ios/build" "android/build" "android/.gradle" ".gradle" ".expo" ".expo-shared")for dir in "${TARGETS[@]}"; do if [ -d "$dir" ]; then xattr -w com.dropbox.ignored 1 "$dir" echo "ignored: $dir" else # For ones not yet generated, pre-create an empty dir and set the attribute mkdir -p "$dir" xattr -w com.dropbox.ignored 1 "$dir" echo "pre-created & ignored: $dir" fidoneecho "done. excluded folders stay local but will not sync."
Pre-creating an empty directory and setting the attribute is the small trick. If you set the attribute while node_modules does not yet exist, whatever the later npm install expands is excluded from the start. Locking in the exclusion before the artifacts are born is what let me create zero conflicted copies.
Confirming it works
Once the attributes are set, leave it a while and observe. I ran development and builds as usual for about three days and confirmed that not a single conflicted copy appeared.
# Periodically count whether conflicted copies are increasingfind . -name "*conflicted copy*" | wc -l# => success if it stays at 0
If the number stays pinned at 0, the tug-of-war between sync and build is over. It is not a flashy result like a dashboard, but the single most demotivating accident — a red build first thing in the morning — was gone.
Wrapping up
Start by running find . -name "*conflicted copy*" once on the project you have open to see whether conflicted copies are mixed into node_modules. If even one shows up, that is the breeding ground for your intermittent build failures.
As an indie developer, all the effort of maintaining your own dev environment comes back to you. I myself repeated "clean and rebuild" many times without grasping the cause. Excluding artifacts from sync is an unglamorous move, but once decided it keeps working quietly. Thank you for reading.
Share
Thank You for Reading
Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.