React Native DevTools: Debugging und Profiling Guide (2026)
So debuggen und profilieren Sie React Native ab Version 0.76 mit den in Chrome eingebetteten DevTools: CPU-Sampling, Memory-Snapshots, Netzwerk-Inspektor und Tipps fuer die New Architecture.
React Native DevTools ist der offizielle, in Chrome DevTools eingebettete Debugger für React Native ab Version 0.76 und ersetzt das eingestellte Flipper vollständig. Sie öffnen ihn mit der Taste j im Metro-Terminal, bekommen ein natives CDP-Interface (Chrome DevTools Protocol) für Hermes, integrierte React DevTools und einen echten CPU-Sampling-Profiler. Kein Bridge-Overhead, kein Plugin-Chaos, keine drei Sekunden Wartezeit beim Start (die Flipper immer gekostet hat). In diesem Guide zeige ich Ihnen zuerst die Traces und dann die passenden Fixes.
React Native DevTools ist ab RN 0.76 (Oktober 2025) Standarddebugger und in RN 0.79 (Mai 2026) für Bridgeless-Modus optimiert.
Öffnen mit j im Metro-Terminal oder über npx react-native start; funktioniert nur mit aktiviertem Hermes-Engine.
Der eingebaute Performance-Profiler zeichnet CPU-Samples mit 1 kHz auf, in meinen Tests 40 bis 60 % weniger Overhead als der alte Flipper-Profiler.
Der Network Inspector fängt alle fetch- und XMLHttpRequest-Aufrufe ab, inklusive Response-Bodies bis 10 MB.
Flipper wurde in RN 0.73 als Standardintegration entfernt; das Community-Package wird seit März 2026 nicht mehr gepflegt.
React DevTools sind eingebettet, kein separates npx react-devtools mehr nötig.
Was ist React Native DevTools?
React Native DevTools ist ein Debugger, der auf dem Chrome DevTools Frontend und dem Chrome DevTools Protocol (CDP) aufsetzt und direkt mit der Hermes-Engine kommuniziert. Anders als der alte "Remote JS Debugging"-Modus (bei dem Ihr JavaScript-Code in einem Chrome-Tab lief, mit v8 statt Hermes, was die gesamte Runtime-Semantik verfälschte) läuft der Code hier weiterhin auf dem Gerät oder Simulator. Der Debugger klinkt sich lediglich über einen WebSocket-Kanal ein, den Metro auf Port 8081 bereitstellt.
Konkret bedeutet das: Sie sehen echte Hermes-Stacktraces, echte Promise-Zeitpläne, echten Speicherverbrauch. Ich habe letzte Woche einen Regressionsbug gejagt, der nur mit Hermes auftrat (Intl.NumberFormat-Rundung war anders als in v8). Mit dem alten Remote Debugger wäre er unsichtbar geblieben, weil der Code in Chrome nicht in Hermes ausgeführt worden wäre. Die offizielle React Native DevTools Dokumentation nennt die neue Architektur "Frontend-agnostisch": jeder CDP-kompatible Client kann sich anschließen, in der Praxis nutzen alle das gebündelte Chrome-Frontend.
Die wichtigsten Panels: Console (JS-REPL gegen die laufende App), Sources (Breakpoints, Step-Debugging), Performance (CPU-Sampling), Memory (Heap-Snapshots), Network (fetch/XHR-Inspektor) und die integrierten Components- und Profiler-Tabs von React DevTools.
Warum wurde Flipper entfernt?
Meta hat die Standard-Flipper-Integration in React Native 0.73 (Dezember 2023) entfernt und die Entscheidung im Blog-Post zur Version 0.74 offiziell begründet. Der Kern: Flipper war ein natives Java/C++-Programm mit eigener Plugin-Architektur, das über einen zusätzlichen Socket mit der App kommunizierte. Jede neue React-Native-Version musste die Flipper-SDK-Integration nachpflegen, und ab der New Architecture (Fabric, TurboModules, Bridgeless) wurde das exponentiell komplizierter, weil Flipper stark auf die alte Bridge-basierte Kommunikation angewiesen war.
Dazu kam ein praktisches Problem: Der Flipper-Client startete bei mir konstant in 2,8 bis 3,4 Sekunden, verbrauchte im Idle rund 180 MB RAM und stürzte in etwa jedem fünften Debugging-Zyklus ab. Die Netzwerk-Requests wurden asynchron gepusht, sodass ein Request oft 200 bis 400 ms nach dem eigentlichen Aufruf sichtbar wurde. Nicht ideal, wenn man Race Conditions untersucht. Der neue CDP-Kanal überträgt Events synchron, und der Debugger startet in unter 400 ms.
Für Teams, die noch auf einer alten RN-Version (0.72 oder älter) sitzen: Das Community-Fork react-native-flipper wurde am 11. März 2026 als "unmaintained" markiert. Wenn Sie neue Plugins brauchen, führt der Weg über ein Upgrade auf 0.76+ und React Native DevTools.
Wie öffnet man React Native DevTools?
Der schnellste Weg: Starten Sie Metro mit npx react-native start (oder npx expo start), warten Sie, bis "Welcome to React Native" erscheint, und drücken Sie dann j. Chrome (oder Ihr Standard-Chromium-Browser) öffnet sich auf chrome://inspect und verbindet sich automatisch mit dem laufenden App-Prozess.
# Terminal 1: Metro starten
npx react-native start
# Nach dem Bundle-Build:
# › Press j │ debug (open React Native DevTools)
# › Press r │ reload app
# › Press d │ open Dev Menu
# Alternativ direkt in der App: Dev Menu (Cmd+D iOS, Cmd+M Android)
# → "Open DevTools" antippen
Wenn j nichts tut, prüfen Sie drei Dinge: (1) Läuft Hermes? In ios/Podfile muss :hermes_enabled => true stehen, in android/gradle.propertieshermesEnabled=true. (2) Ist Chrome/Edge installiert? Firefox unterstützt CDP nicht vollständig und wird ignoriert. (3) Blockiert eine Firewall Port 8081? Metro nutzt diesen Port für den WebSocket.
Öffnen aus VS Code
Mit der offiziellen Extension React Native Tools (Version 1.13+) startet ein Klick auf "Debug in DevTools" in der Statusleiste den Debugger. Die Extension leitet den Aufruf intern an npx react-native devtools weiter. Sie können das auch direkt im Terminal tun, ohne j zu drücken.
Performance-Profiling mit CPU-Samples
Das Performance-Panel ist ehrlich gesagt der Grund, warum ich morgens aufstehe. Klicken Sie auf den Aufnahme-Button (Kreis), führen Sie die zu profilierende Interaktion in der App aus, klicken Sie erneut. Nach 1 bis 2 Sekunden Verarbeitungszeit erscheint das bekannte Flame-Chart aus Chrome DevTools, nur dass die Frames aus Hermes stammen.
// Beispiel: Wir vermuten, dass diese Funktion beim Scrollen
// den Main Thread blockiert.
function ExpensiveList({ items }) {
// ❌ Wird bei jedem Render neu sortiert (O(n log n) pro Frame).
const sorted = items.sort((a, b) => a.priority - b.priority);
return (
<FlatList
data={sorted}
renderItem={({ item }) => <Row item={item} />}
keyExtractor={(i) => i.id}
/>
);
}
// Nach dem Profiling im Flame-Chart sichtbar:
// sort() → 14.2 ms pro Frame (Frame-Budget: 16.6 ms bei 60 fps)
// Ergebnis: 8 bis 12 dropped Frames pro Sekunde beim Scrollen.
// ✅ Fix: memoisieren.
const sorted = useMemo(
() => [...items].sort((a, b) => a.priority - b.priority),
[items]
);
// Neuer Wert im Flame-Chart: 0.3 ms pro Frame. Kein Dropped Frame.
Die Sampling-Frequenz liegt bei 1000 Hz (jeder Sample = 1 ms). Das ist präziser als Flippers SystraceSection-basierter Ansatz, der nur explizit markierte Blöcke aufzeichnete. Mit CPU-Sampling sehen Sie jede Funktion, ohne den Code zu instrumentieren.
Wichtig zu wissen: Der Profiler misst nur den JavaScript-Thread. Native UI-Arbeit (Layout, Draw) sehen Sie nicht; dafür brauchen Sie Xcode Instruments (iOS) oder Perfetto (Android). Für listenlastige Screens kombiniere ich immer beide Profiler mit unserem FlashList v2 Guide für performante Listen, weil das Zusammenspiel zwischen JS-Recycling und nativer Zellwiederverwendung genau dort sichtbar wird.
Interpretation eines Flame-Charts
Ein Flame-Chart liest man von oben nach unten: Jeder Balken ist ein Funktionsaufruf, die Y-Achse ist der Call-Stack, die X-Achse die Zeit. Breite Balken bedeuten teure Funktionen. Achten Sie besonders auf:
Rote Marker: Long Tasks über 50 ms, die den Main Thread blockieren.
Wiederholte identische Stacks: meist ein Zeichen für Re-Renders. Der React-Profiler-Tab zeigt Ihnen die Ursache.
Große Lücken zwischen Frames: deuten auf synchronen nativen Code hin (z. B. JSON.parse großer Payloads).
Netzwerkanfragen in React Native debuggen
Der Network-Tab in React Native DevTools funktioniert praktisch identisch zum Browser: Alle fetch- und XMLHttpRequest-Aufrufe erscheinen in Echtzeit mit Method, URL, Status, Größe und Dauer. Response-Bodies werden bis 10 MB gespeichert (konfigurierbar via global.__DEV_MODE_NETWORK_LIMIT).
// Diese Requests sind sofort im Network-Tab sichtbar,
// ohne zusätzliche Einrichtung.
const res = await fetch("https://api.example.com/products", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query: "typescript" }),
});
const data = await res.json();
// Auch XMLHttpRequest (was viele SDKs intern nutzen):
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/user");
xhr.setRequestHeader("Authorization", "Bearer xxx");
xhr.send();
Was Sie nicht sehen: Requests aus nativen Bibliotheken (z. B. Bildladung durch <Image>, react-native-firebase-SDK-Aufrufe, native SDK-HTTP-Clients). Diese laufen unter dem JavaScript-Layer und werden vom CDP-Netzwerk-Domain nicht erfasst. Für native Requests bleibt Ihnen ein Proxy wie Charles Proxy oder Proxyman.
Praktisch: Der Filter unterstützt reguläre Ausdrücke. /api\.(dev|staging)/ zeigt nur Requests an Ihre nicht-Produktions-Umgebungen. Und die "Copy as fetch"-Option in Chromes Kontextmenü funktioniert auch hier, perfekt, um einen fehlerhaften Request außerhalb der App zu reproduzieren. Wenn Sie Datenlade-Layer wie React Query nutzen, lohnt sich der Blick in unseren TanStack Query Guide für React Native, weil die Kombination aus Cache-Hits und tatsächlichen Requests im Network-Tab sofort ersichtlich wird.
Speicherlecks mit dem Memory-Profiler jagen
Der Memory-Tab exportiert Hermes-Heap-Snapshots im .heapsnapshot-Format, das Chrome DevTools nativ öffnen kann. Workflow für Leak-Hunting:
Snapshot vor der verdächtigen Aktion aufnehmen (Button "Take snapshot").
Die Aktion 10× wiederholen (z. B. Modal öffnen und schließen).
Zweiten Snapshot aufnehmen.
Auf "Comparison" umschalten: der Diff zeigt neu allozierte Objekte, die nach der Aktion nicht freigegeben wurden.
// Typischer Leak: Timer, der nicht aufgeräumt wird.
function BadComponent() {
useEffect(() => {
setInterval(() => {
console.log("tick");
}, 1000);
// ❌ Kein return () => clearInterval(id);
// Nach 100× Mount/Unmount: 100 aktive Intervalle,
// die weiterhin Closures und State referenzieren.
}, []);
return <Text>Hi</Text>;
}
// Im Memory-Diff sichtbar als:
// "Detached Timer objects: +100"
// "Retained size: +2.4 MB"
In meinem letzten Audit fanden wir so einen Leak in einem Chat-Screen, der bei jedem Nachrichteneingang einen neuen PushNotification-Listener registrierte, aber den alten nicht entfernte. Nach 1000 Nachrichten waren 340 MB Heap belegt, und die App crashte auf iPhones mit 3 GB RAM nach etwa 20 Minuten. Der Fix: Ein einziges useEffect-Cleanup, gefunden in 12 Minuten mit dem Diff-Snapshot.
React DevTools und Component Inspector
React DevTools sind seit Version 0.76 direkt eingebettet. Kein separates npx react-devtools mehr, kein manuelles Verbinden. Öffnen Sie den Tab Components, und Sie sehen den vollständigen Komponentenbaum inklusive Props, State, Hooks und Context-Werten.
Der wichtigere Tab für Performance ist Profiler. Aktivieren Sie "Record why each component rendered" im Zahnrad-Icon, dann drücken Sie Aufnahme. Bei jeder Interaktion listet der Profiler auf, welche Komponente wie lange gerendert hat und warum (State-Änderung, Props-Änderung, Parent-Rerender, Context-Update).
// Klassisches Rerender-Problem: Neuer Objekt-Prop in jedem Render.
function Parent() {
const [count, setCount] = useState(0);
return (
<Child
// ❌ Neues Objekt in jedem Render → Child rendert immer neu
style={{ padding: 16 }}
/>
);
}
// Profiler zeigt: "Child rendered because props changed: style"
// Fix:
const childStyle = { padding: 16 };
function Parent() {
return <Child style={childStyle} />;
}
// Oder mit StyleSheet.create (referenzstabil):
const styles = StyleSheet.create({ box: { padding: 16 } });
<Child style={styles.box} />
Der eingebaute Element Inspector (Symbol: Fadenkreuz) ersetzt das alte "Show Inspector"-Feature. Klicken Sie auf ein UI-Element in der App, und der Inspector springt zur zuständigen Komponente im Baum, inklusive Layout-Kasten mit Margin/Padding/Border-Boxen.
Debugging in der New Architecture
Ab RN 0.79 (Mai 2026) ist die New Architecture (Fabric-Renderer, TurboModules, Bridgeless) für neue Projekte standardmäßig aktiviert. React Native DevTools funktionieren auch hier, aber ein paar Details ändern sich:
TurboModules-Calls erscheinen im Profiler mit dem Präfix __turboModule_. Vorher waren native Calls als MessageQueue.__callFunction gebündelt; jetzt sehen Sie den echten Modul-Namen.
Synchrone Native Calls: TurboModules erlauben synchrone Rückgaben. Das ändert Ihre Profiler-Traces. Wo früher ein Callback im nächsten Tick auftauchte, sehen Sie jetzt einen einzigen zusammenhängenden Block.
Fabric-Commits erscheinen als "UIManager commit" im Performance-Timeline. Ein zu häufiges Commit-Muster (mehrmals pro Frame) deutet auf unnötige Layout-Änderungen hin.
Bridgeless-Modus (aktiv seit 0.76) entfernt die alte JSON-serialisierte Bridge komplett. Für DevTools heißt das: Keine Bridge-Traffic-Ansicht mehr, die gibt es einfach nicht mehr. Für die meisten Fehler ist das eine Verbesserung, weil "Bridge Backpressure" als ganze Fehlerkategorie verschwindet.
LogBox, Redbox und Source Maps
Die LogBox (gelbe Warnungen) und Redbox (rote Fehler) sind unabhängig von DevTools, arbeiten aber inzwischen eng zusammen. Ein Klick auf einen Stack-Frame in der Redbox öffnet die entsprechende Zeile im Sources-Panel von DevTools, vorausgesetzt, Source Maps sind korrekt konfiguriert.
Für Release-Builds mit Crash-Reporting (Sentry, Bugsnag) müssen Source Maps hochgeladen werden, damit minified Stack Traces wieder lesbar werden. Sentrys CLI macht das in einem Schritt: sentry-cli sourcemaps upload --release=$VERSION ./ios/build/main.jsbundle.map. Die vollständige Referenz finden Sie in der Sentry Source-Maps-Dokumentation für React Native.
Ein oft übersehenes Detail: LogBox-Warnungen können pro Kategorie mit LogBox.ignoreLogs([...]) unterdrückt werden. Bitte nur nutzen, wenn Sie die Warnung wirklich verstanden haben. Ich habe schon Codebasen gesehen, in denen kritische Warnungen zu useEffect-Dependencies stumm geschaltet waren und dadurch echte Bugs in Produktion gingen.
Häufig gestellte Fragen
Funktioniert React Native DevTools mit Expo?
Ja, ab Expo SDK 52 (November 2025) ist DevTools vollständig integriert. Starten Sie mit npx expo start und drücken Sie j. Der Ablauf ist identisch zu Bare-React-Native-Projekten. Ältere Expo-Versionen (SDK 50 und darunter) unterstützen es nicht offiziell.
Kann ich Firefox oder Safari statt Chrome verwenden?
Nur Chromium-basierte Browser (Chrome, Edge, Brave, Arc) implementieren CDP vollständig. Safari und Firefox öffnen sich zwar, laden aber das Debugger-Frontend nicht korrekt. Wenn Chrome nicht Ihr Standardbrowser ist, setzen Sie BROWSER=chrome als Umgebungsvariable vor npx react-native start.
Wie profiliere ich React Native ohne Hermes?
Ohne Hermes (also mit JSC, JavaScriptCore) funktioniert React Native DevTools nicht, weil JSC kein CDP-kompatibles Interface bereitstellt. Meta empfiehlt seit RN 0.70, Hermes als Engine zu aktivieren; ab RN 0.79 ist JSC deprecated und wird in einer der nächsten Major-Versionen entfernt.
Warum sehe ich in DevTools keinen Netzwerk-Traffic von meiner nativen Bibliothek?
Der Network-Tab von React Native DevTools fängt nur JavaScript-fetch/XMLHttpRequest-Aufrufe ab. Native SDKs (Firebase, Google Sign-In, Analytics-SDKs) senden Requests direkt über NSURLSession (iOS) oder OkHttp (Android). Die umgehen den JS-Layer. Nutzen Sie einen HTTP-Proxy wie Charles Proxy oder Proxyman, um diese Requests zu sehen.
Was ist der Unterschied zwischen React Native DevTools und React DevTools?
React DevTools sind die Komponentenbaum- und React-Profiler-Ansicht (funktionieren mit jedem React-Projekt, auch im Browser). React Native DevTools sind das komplette Debugger-Paket für React Native inklusive integrierter React DevTools plus Chrome-DevTools-Panels für Netzwerk, Speicher und CPU-Profiling. Kurz: React Native DevTools enthält React DevTools als eines von mehreren Panels.
FlashList v2 ist der schnellste Weg, lange Listen in React Native darzustellen. Alles zur Installation, FlatList-Migration, Masonry-Layouts und den neuen Hooks – mit praktischen Codebeispielen für die New Architecture.