CORE JSC

International Technology Partnership

VS Code / Tools

Fixing VS Code Debugger Breakpoints That Don't Hit in React Native Apps (Source Map Misconfiguration)

The debugger attaches, the app runs, logs appear — but breakpoints never hit, or hit the wrong line. The JavaScript is executing fine; the debugger just can't map it back to your source. Here's why, and the definitive fix.

Core JSC Team·July 31, 2026
VS CodeReact NativeDebuggingSource MapsMetroHermes

The Problem

Setting a breakpoint in VS Code on a React Native project looks like it should work — the debugger attaches, the app runs, logs appear in the console — but the breakpoint is never hit, or it's hit on the wrong line, or stepping through code jumps to seemingly unrelated locations. The JavaScript is genuinely executing; the debugger just can't map what's running back to the source file you're looking at.

Why It Happens

Metro bundles and transforms the code before it ever runs

The JavaScript actually executing on the device or in Hermes isn't the file open in the editor — it's a single bundled, transformed (Babel/TypeScript-compiled) file produced by Metro. The debugger can only land breakpoints on the right original line if it has an accurate source map translating positions in that bundle back to positions in the original source.

A stale or mismatched source map is worse than no source map

If Metro's cache is out of date relative to the actual source (a common state after switching branches, pulling changes, or a crashed bundler process), the source map it serves describes an older version of the bundle than the one actually running — breakpoints land on the wrong line because the map itself is wrong, not because debugging is broken.

The debugger configuration doesn't match how the app is actually being run

A VS Code launch configuration pointed at the wrong port, the wrong bundler target (Hermes debugger vs. the older JSC-based remote debugger), or missing the correct sourceMapPathOverrides for a monorepo layout will attach successfully but silently fail to resolve breakpoints correctly.

The Fix

1. Clear Metro's cache and restart with a clean state

npx react-native start --reset-cache

This is the fastest fix for the single most common cause: a stale bundle/source-map pair left over from before a branch switch or dependency change. Restart the app fresh after this, not just reload it.

2. Use the official React Native / Hermes debugger extension, not the legacy remote JS debugger

Hermes (the default JS engine on modern React Native) has its own debugging protocol distinct from the older Chrome-based remote debugger. Debugging through the react-native-tools / official React Native VS Code extension against Hermes gives far more reliable breakpoint mapping than opening chrome://inspect against an app that's actually running Hermes.

3. Set sourceMapPathOverrides for monorepos or non-standard layouts

// .vscode/launch.json
{
  "type": "reactnative",
  "request": "launch",
  "name": "Debug Android",
  "platform": "android",
  "sourceMapPathOverrides": {
    "/packages/*": "${workspaceFolder}/packages/*"
  }
}

If the app lives inside a monorepo package, or the bundler's working directory doesn't match the debugger's assumed project root, the source map's file paths won't resolve to real files on disk without an explicit override telling the debugger how to translate them.

4. Confirm the exact JS engine and build variant match what you're debugging

A debug build running Hermes needs a Hermes-aware debug session; attaching a JSC-style debugger to a Hermes-running app (or vice versa) can appear to connect successfully while never actually resolving breakpoints, because the two engines expose fundamentally different debugging protocols.

Why This Works

None of this changes what the app's code does — it re-establishes the accurate mapping the debugger needs between the bundle that's actually executing and the source files you're looking at. A fresh Metro cache guarantees the bundle and its source map describe the same code; the right debugger-engine pairing means the protocol itself understands where you are; and explicit path overrides fill in what the debugger can't infer on its own about a non-default project layout.

Conclusion

Breakpoints that silently don't hit in a React Native project are almost always a source-map mismatch, not a genuine debugger failure — a stale Metro cache, the wrong debugger-engine pairing for Hermes, or missing path overrides in a monorepo. Reset the bundler cache first, confirm you're using a Hermes-aware debugger, and add explicit source map overrides where the project layout needs them.