Skip to main content

Build speed and caches

Commands use stim. If it is not installed globally, replace stim with npx stim.

Stim shares four types of work across projects and git worktrees:

LayerWhat it avoids
Native artifact cacheA complete iOS or Android build when native inputs match
Xcode compilation cacheRecompiling unchanged native units on an artifact miss
Gradle caches and outputRepeating Android dependency and task work
Metro transform cacheTransforming the same JavaScript modules in each worktree

See build optimizations for switches, defaults, and tradeoffs for each layer, including Android ccache, PCH, and experimental CAS.

Native artifact cache

Stim uses @expo/fingerprint to identify native inputs in both Expo and bare React Native projects. The cache key also includes the platform, target, and build configuration or variant.

stim ios and stim android first check the machine-wide artifact cache. A hit installs the saved .app or .apk. A miss runs the native build and stores the result. Two matching misses use one build through a single-flight lock.

Release configurations use separate keys. On a cache hit for an iOS simulator or Android target, Stim regenerates the current workspace's JavaScript and assets in a copy of the artifact. If that swap fails, it builds fresh. iOS physical-device Release runs always build fresh.

Optional artifact providers

The provider integration is implemented, but Stim ships no network provider or hosted cache service. Without a configured provider, artifacts stay on the local machine.

Projects can supply a module through cache.provider using the @stim-cli/cache contract, or use a configured Expo buildCacheProvider, such as eas. optimizations.remoteBuildCache controls whether Stim uses those providers. Provider and build-profile restrictions still apply; see build optimizations. This caches app artifacts; ccache and Clang CAS use separate compiler caches.

Keep the main checkout warm

Run stim doctor before native worktree work. It checks whether the main checkout has current dependencies and CocoaPods state. On a checkout without installed dependencies, it also checks whether a fresh worktree produces the same native fingerprint.

When several native tasks are coming, build the main checkout once:

stim start
stim ios # or: stim android
stim stop

Later worktrees can reuse that cache entry. In an existing linked worktree, stim worktree warm copies missing ignored state from main without replacing existing entries. This includes installed dependencies, Pods, and native output. See worktree isolation for its full scope.

Inspect and clean caches

stim gc
stim gc --delete --older-than 30
stim gc --delete --cache all

The first command only reports sizes. Age-based cleanup removes unused entries. --cache all empties managed caches and makes future builds cold; it reaps nothing, so gc --delete on its own remains the way to prune stale entries. --cache "compilation cache" empties one cache instead of every one.

Set STIM_BUILD_CACHE or STIM_METRO_CACHE to place the shared caches on a different volume. The same values can live in the machine config under caches.buildCache and caches.metroCache.