Fix React Native 'Unable to resolve module' red screens from stale Metro cache
Reset Metro and Watchman caches to fix React Native red screens caused by stale module resolution after installs, branch switches, or upgrades.
16 Dec 2025, 12:54 UTC

Problem: red screen after a dependency install, branch switch, or React Native upgrade
You start Metro with npx react-native start or run npx react-native run-ios or npx react-native run-android. The app opens and immediately shows a red screen with an error such as 'Unable to resolve module ./src/components/Button' or 'Module not found'. The file exists, and the same code worked before you changed branches, installed a package, or upgraded React Native.
Useful takeaway: this is usually a stale cache problem, not missing source code. Metro (the development bundler that transforms JavaScript and serves it to the running app) may be holding an outdated module map or transformed bytecode. Resetting the cache and the file watcher resolves most cases without touching node_modules.
Terms used in this guide
- Metro bundler: the React Native development server that bundles and transforms JavaScript for iOS and Android simulators or devices.
- Hermes: the default JavaScript engine in React Native 0.74 and later; older projects may use JavaScriptCore (JSC). Hermes bytecode is stored separately from JSC output.
- Watchman: a file-watching service used by Metro on macOS and Linux to detect changes in
node_modulesand project files. Windows support is limited.
Cause and diagnostic table
| Recognizable condition | Most likely cause | First check |
|---|---|---|
Red screen appears immediately after npm install, yarn install, or pod install |
Stale Metro cache holds an outdated module map | Run Metro with --reset-cache |
| Red screen appears after switching Git branches | Watchman or Metro cache still references deleted or renamed files | Reset Watchman, then reload the app |
| Metro starts but the app cannot connect, or a second Metro instance seems to run | Another process is occupying port 8081 | Check what is listening on port 8081 |
| Error persists after cache resets on a freshly cloned repository | Native dependencies are not linked or installed | Reinstall CocoaPods (iOS) or sync Gradle (Android) |
Ordered checks and fixes
1. Confirm Metro is running and capture the exact error
Open a terminal in the project root and run:
npx react-native start
Expected check: Metro should print a line similar to React Native Metro and report that it is listening on port 8081. If you see a port-conflict error, skip to check 4. If Metro crashes, note the exact module name in the red-screen message; you will use it to verify the fix later.
Risk: do not edit files inside node_modules to force a match. Edits are lost on reinstall and can hide the real cache problem.
2. Reset the Metro cache
Stop the running Metro process (Ctrl+C in its terminal), then restart with the cache-reset flag:
npx react-native start --reset-cache
Where to run: project root, in the terminal used for Metro. Permissions: normal user account is sufficient. Expected check: the first startup takes longer than usual because Metro re-transforms the bundle. After it finishes, reload the app (Cmd+R on iOS simulator, double-tap R on Android, or use the developer menu) and confirm the red screen no longer references the same module.
Limitation: clearing the cache forces a full re-transform on the next start. On large projects the first build can be significantly slower. Metro regenerates the cache automatically, so there is no manual rollback to perform; if you want the previous cache back, you would have to wait for Metro to rebuild it, which happens on the next start.
3. Reset Watchman (macOS and Linux only)
If the error appeared after switching branches or deleting a package, Watchman may still report the old file tree.
watchman watch-del-all
Where to run: project root or any terminal on macOS/Linux. Permissions: normal user. Expected check: run the command, then restart Metro with --reset-cache and reload the app. The module resolution error should disappear if Watchman was the cause.
Limitation: Watchman support on Windows is limited. On Windows, rely on Node file watching and skip this step.
4. Check for a port 8081 conflict
Metro defaults to port 8081. Another Metro instance, a previous bundler, or an unrelated service can occupy it.
lsof -i :8081
Where to run: macOS/Linux terminal. On Windows, use netstat -ano | findstr :8081 in Command Prompt or PowerShell. Expected check: if a process other than the Metro you just started is listening, stop that process or start Metro on a different port, for example:
npx react-native start --port 8082
Then update the app's bundle URL configuration to point to 8082 if your project hardcodes 8081.
Risk: killing the wrong process can stop an unrelated service. Verify the process name before terminating it.
5. Verify native dependency installation
If the unresolved module is a native library you just installed, cache resets alone will not fix missing native code.
- iOS: run
npx pod-installin the project root, then rebuild in Xcode. - Android: sync the Gradle project in Android Studio or run
./gradlew cleanfrom theandroiddirectory.
Expected check: after native install and rebuild, start Metro without --reset-cache and confirm the module loads.
Escalation criteria
Escalate beyond cache resets when any of the following is true:
- The same red screen remains after Metro cache reset, Watchman reset, and port check.
- The error occurs only on iOS or only on Android after a native module upgrade.
- The module resolves in a brand-new React Native project but not in yours, suggesting a project-specific configuration issue such as a custom Metro config or incorrect
modulePaths. - You are on React Native 0.74 or later with Hermes enabled and the error mentions Hermes bytecode paths; verify your
react-native.config.jsand Hermes version match the project's React Native version.
Practical verification
After applying a fix, reload the app and check the Metro terminal. You should see successful transform logs for the previously missing module and no red screen. If the error returns immediately after a code change, the issue is likely Watchman rather than the Metro cache; repeat step 3.
Limitations
- Cache reset does not fix broken native linking, invalid package exports, or TypeScript path mismatches that Metro cannot resolve.
- First build after reset is slower on large projects.
- Windows users should not rely on Watchman; use Node-based watching.
- This guide covers CLI-managed projects. Expo-managed projects use different cache-clearing commands.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.