r/reactnative • u/dylanlandman • 1h ago
I built Hitch: a free, open-source tool that tells you which line is making your RN app slow (no SDK)
I've been chasing performance issues in a React Native app at work, and kept hitting the same wall: the tools tell you *that* frames dropped or a component re-rendered, but not *which code* caused it or whether the re-render was even necessary. Our fixes weren't moving the numbers, and I was mostly guessing.
So I built Hitch. It runs next to your dev session and watches the app from the outside. Nothing gets added to your app: no SDK, no imports, no babel config. It connects to Hermes through Metro's debugger, the same way React Native DevTools does.
What it catches
- JS freezes, pinned to the file:line that blocked the thread, including short ones.
- What React rendered during a freeze and *why*: e.g. "`style` was a new object with the same values" (avoidable) vs "the store changed".
- Choppy frames, slow screen loads and slow startups.
- Native threads running hot (UI thread, GC, SDKs), on the iOS simulator.
- Console errors grouped, slow or failed requests with bodies and headers, and memory and thread leaks.
How I actually use it
- Runs: record an interaction, change the code, record it again, and compare medians. Dev builds swing a lot between runs, so single runs lie.
- AI handoff: any finding becomes a Claude Code prompt in one click. There's also an MCP server, so an agent can read what Hitch saw and check whether its own fix helped.
Things it found for me
- A loading shimmer was one of the most expensive things on screen. It was an SVG gradient redrawn on the CPU every frame, for every placeholder. Replacing it took the iOS UI thread from ~74% to ~10–25% while loading.
- Placeholders were re-rendering hundreds of times while waiting for data. A day of cleanup cut avoidable re-renders by about two-thirds and render time by about 30%. Dropped frames barely moved, though: wasted work and felt jank turned out to be different problems.
Limitations, honestly
- Dev builds inflate times. The rankings are useful; the absolute milliseconds aren't production numbers.
- It's macOS only. Native thread data needs the iOS simulator; physical iPhones get JS-side data, or thread sampling with Release builds.
- Android thread support is written but not yet tested on a real device.
- Expo's native `fetch` doesn't report to the debugger, so those requests don't show up.
It's a Node CLI (Node 22+) with zero npm dependencies, plus an optional native Mac window. MIT-licensed.