How to Debug Faster and Better with Flipper

Authors
Jakub Mazurek
Software Engineer
@
Callstack

The debugging process is one of the most important elements of mobile app development. But, as you probably know, this process can be time-consuming and may not be the most enjoyable part of your work if it's not managed well. In this article, we will tell you how to make the debugging process faster, better, and more enjoyable.

What are the challenges in debugging?

Debugging is one of the more challenging parts of every developer’s daily work and finding out what is wrong can be very frustrating. We usually try to fix bugs as soon as possible, especially when they are critical and make an app unfunctional. Time is an important factor in that process and we usually have to be agile to quickly solve the issues.

However, debugging React Native is not very straightforward as the issue you are trying to solve may occur on different levels. Namely, it may be caused by:

  • JavaScript: your application’s code or React Native, or
  • Native code: third-party libraries or React Native itself.

Debugging native code and JavaScript code

When it comes to debugging native code, you have to use the tools built into Android Studio and Xcode. And when it comes to debugging JavaScript code, you may encounter several difficulties. The first and most “naive” way to debug is to write console.logs in your code and check logs in the terminal. This method works only for solving trivial bugs or when following the divide and conquer technique. In all other cases, you may need to use an external debugger.

By default, React Native ships with built-in debugging utilities.

Built-in debugging utilities in React Native

The most common one is the Google Chrome Remote Debugger. It allows you to set breakpoints in your code or preview logs in a handier way than in a terminal. Unfortunately, using the RemoteDebugger may lead to hard-to-spot issues. It’s because your code is executed in Chrome’s V8 engine instead of a platform-specific engine, such as JSC or Hermes.

The instructions generated in Chrome are sent via Websocket to the emulator or device. It means that you cannot use the debugger to profile your app so it detects the performance issues. It can give you a rough idea of what might cause the issues, but you will not be able to debug the real cause due to the over head of WebSocket message passing.

Another inconvenience is the fact that you cannot easily debug network requests with the Chrome Debugger (it needs additional setup and still has its limitations). In order to debug all possible requests, you have to open a dedicated network debugger using the emulator’s developer menu. However, its interface is very small and inconvenient due to the size of the emulator’s screen.

From the developer menu, you can access other debugging utilities, such as layout inspector or performance monitor. The latter is relatively convenient to use as it displays only a small piece of information. However, employing the former is a struggle because of the limited workspace it provides.

Longer debugging means worse developer experience

Unlike native developers, the ones working with React Native have access to a wide range of debugging tools and techniques. Each originates from a different ecosystem, such as iOS, Android, or JS. While it may sound great at first, you need to remember that every tool requires a different level of expertise in the native development. That makes the choice challenging for the vast majority of JavaScript developers.

Inconvenient tooling usually decreases the velocity of the team and frustrates its members. As a result, they are not as effective as they could be, affecting the quality of the app and making the releases less frequent.

Turn on Flipper to debug faster and better

Wouldn’t it be great to have one comprehensive tool to handle all those use cases? Of course, it would! And that’s where Flipper comes into play!

Flipper is a debugging platform for mobile apps. It also supports React Native as its first-class citizen. Launched in September 2019, Flipper has been shipped by default with React Native since version 0.62.

screenshot with flipper features
Source: https://fbflipper.com/docs/features/react-native

It is a desktop app with a convenient interface, which directly integrates with your application’s JS and native code. This means that you no longer have to worry about JS runtime differences and the performance caveats of using the Chrome Remote Debugger. It comes with a network inspector, React DevTools, and even a native view hierarchy tool.

Also, Flipper lets you preview logs from native code and track native crashes, so you don’t have to run Android Studio or Xcode to check what is happening on the native side.

Flipper is easily extensible, so there is a high chance it will be enriched with a wide range of useful plugins developed by the community. At this point, you can use Flipper for tasks such as detecting memory leaks, previewing the content of Shared Preferences, or inspecting loaded images. Additionally, Flipper for React Native is shipped with React DevTools, Hermes debugger, and Metro bundler integration.

What’s most exciting is that all the needed utilities are placed in one desktop app. That minimizes context switches. Without Flipper, a developer debugging an issue related to displaying the data fetched from the backend had to use Chrome debugger (to preview logs), an in-emulator network requests debugger, and probably an in-emulator layout inspector or standalone React Dev tools app. With Flipper, all those tools are available as built-in plugins. They are easily accessible from a side panel and have similar UI and UX.

Enjoy better feedback loop with Flipper

A better debugging process makes your app development cycle faster and more predictable. As a result, your team can produce more reliable code and spot any kind of issues much easier.

Having all debugging utilities in one interface is definitely ergonomic and does not disrupt any interactions with an emulator or device. The process will be less burdensome for your team and that will positively impact the velocity of the product development and bug fixing.

"Feel like a functionality is missing in Flipper? Good news! Flipper is easily extensible and has a comprehensive guide on how to write custom plugins in React. Why not build your own?"
Alexandre Moureaux – App performance specialist at BAM

Need help with performance?

If you’re struggling with improving your app performance, get in touch with us. We’re the official Meta and Vercel partners and active contributors to the community. We’ve delivered high-quality solutions for dozens of international clients, from startups to enterprises. Whatever React Native development needs your organization might have, we’ve got you covered.

Insights

Learn more about Developer Experience

cover

May 5Article

Codex Ambassador: Q1 Recap Across 5 Cities

A short recap of Codex events in Berlin, Wroclaw, Warsaw, Sopot, and Miami, plus what we learned from each format and where we want to go next.

cover

Feb 5Live Stream

Storybook Explained: From Basics to Advanced Workflows

Core Storybook concepts, stories and args, interaction testing, and how Storybook works in React Native projects.

cover

Jan 29Article

Announcing AI SDK Profiler for React Native

Announcing the AI SDK Profiler plugin for Rozenite DevTools. Capture OpenTelemetry spans from the Vercel AI SDK and inspect AI requests across on-device and cloud providers.

cover

Nov 28Talk

How I Hacked React Native DevTools (And Built a Plugin Framework)

Learn how React Native DevTools work under the hood, and how to inject custom plugins with clean hooks and no forks.

cover

Sep 16Talk

How I Hacked React Native DevTools (And Built a Plugin Framework)

Learn how React Native DevTools work under the hood, and how to inject custom plugins with clean hooks and no forks.

cover

Jul 28Article

Introducing Rozenite: A Plugin Framework for React Native DevTools

Build custom debugging panels inside React Native DevTools with Rozenite: a modular, TypeScript-ready plugin framework with full device-scoped support.

cover

Feb 12Article

How to Easily Create Native Libraries With Nitro and Turbo Modules

Learn how to optimize React Native performance with Turbo and Nitro Modules. Ditch the legacy bridge and master modern native module development.

cover

Dec 4Podcast

Radon IDE: Better Developer Experience for React Native Teams

Find out how Radon IDE can help increase team velocity and rid you of the common React Native app development pain points.

cover

Sep 19Podcast

Exploring Bun: Jarred Sumner on Hyperfast JavaScript Toolkit

Is Bun the future of React Native package management? Join us as we talk with Jarred Sumner, the creator of this lightning-fast JavaScript toolkit.

cover

Sep 11Podcast

Vim: from Zero to Hero

Discover the power of Vim, the legendary text editor, as we explore its origins, standout features, and practical tips to boost your coding efficiency.

cover

May 15Article

Add-Ons for Web Browsers With React

At times you may need to create an add-on to use a web browser more effectively. Find out how to build one with React.

cover

Jan 27Article

Why Is It Worth to Automate Your Dependency Management with `Autolinking`?

When you automate your dependency management, you can fully focus on developing your app. Find out how you can do it with autolinking.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.