DEV Community

Cathy Lai
Cathy Lai

Posted on

How to Set Up Reactotron to Debug AsyncStorage in React Native

Why You Need This

If you're building a React Native app with local storage, you've probably wondered: "Is my data actually being saved?" or "What does my AsyncStorage look like right now?"

Sure, you could console.log everything, but that gets messy fast. Enter Reactotron — a powerful desktop app that lets you inspect AsyncStorage, monitor network requests, and debug your React Native app like a pro.

In this guide, I'll show you how to set up Reactotron in an Expo React Native app and configure it to inspect AsyncStorage. Let's dive in! 🚀


Prerequisites

Before we start, make sure you have:

  • A React Native/Expo project set up
  • @react-native-async-storage/async-storage installed
  • Node.js and npm installed
  • Basic familiarity with React Native

Step 1: Install Reactotron Packages

First, install the necessary Reactotron packages as development dependencies:

npm install --save-dev reactotron-react-native reactotron-react-js
Enter fullscreen mode Exit fullscreen mode

Why both packages?

  • reactotron-react-native provides React Native-specific debugging features
  • reactotron-react-js is required as a peer dependency

Step 2: Create Reactotron Configuration

Create a new file at config/reactotron.ts (or config/reactotron.js if you're not using TypeScript):

import AsyncStorage from '@react-native-async-storage/async-storage';
import Reactotron from 'reactotron-react-native';

// Only configure Reactotron in development
if (__DEV__) {
    Reactotron
        .setAsyncStorageHandler(AsyncStorage) // Enable AsyncStorage inspection
        .configure({
            name: 'YourAppName',
            host: 'localhost', // Change to your IP if using a physical device
        })
        .useReactNative({
            asyncStorage: true, // Track AsyncStorage changes
            networking: {
                ignoreUrls: /symbolicate/, // Ignore symbolication requests
            },
            editor: false,
            errors: { veto: () => false },
            overlay: false,
        })
        .connect();

    // Clear Reactotron on app load for a fresh start
    Reactotron.clear!();

    console.log('Reactotron Configured');
}

export default Reactotron;
Enter fullscreen mode Exit fullscreen mode

Key Configuration Options:

  • setAsyncStorageHandler(AsyncStorage): This is crucial! It tells Reactotron how to access your AsyncStorage.
  • host: 'localhost': Works for simulators/emulators. For physical devices, replace with your computer's IP address (e.g., '192.168.1.100').
  • asyncStorage: true: Enables AsyncStorage monitoring in the Reactotron UI.
  • __DEV__: Ensures Reactotron only runs in development, not production.

Step 3: Import Reactotron in Your App Entry Point

Now, we need to import Reactotron before anything else in your app. In an Expo Router app, this is typically app/_layout.tsx (or App.tsx in standard React Native).

Important: Use conditional require() to ensure it only loads in development:

// app/_layout.tsx
import { MaterialIcons } from "@expo/vector-icons";
import { Tabs } from "expo-router";

// Load Reactotron only in development
if (__DEV__) {
    require("../config/reactotron");
}

import { HousesProvider } from "../contexts/HousesContext";
import "../global.css";

export default function RootLayout() {
    return (
        <HousesProvider>
            <Tabs>
                {/* Your tabs configuration */}
            </Tabs>
        </HousesProvider>
    );
}
Enter fullscreen mode Exit fullscreen mode

Why conditional require?

  • Using require() inside if (__DEV__) ensures the Reactotron code is completely excluded from production builds
  • This keeps your production bundle size small
  • It prevents any Reactotron code from running in production

Step 4: Add TypeScript Types (Optional)

If you're using TypeScript, create a type definition file to avoid errors:

Create reactotron-env.d.ts in your project root:

/// <reference types="reactotron-react-native" />

import Reactotron from 'reactotron-react-native';

declare global {
  interface Console {
    tron: typeof Reactotron;
  }

  var __DEV__: boolean;
}

export {};
Enter fullscreen mode Exit fullscreen mode

Then update your tsconfig.json to include this file:

{
  "include": [
    "**/*.ts",
    "**/*.tsx",
    ".expo/types/**/*.ts",
    "expo-env.d.ts",
    "reactotron-env.d.ts"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Download Reactotron Desktop App

Download the Reactotron desktop application from the official releases:

👉 https://github.com/infinitered/reactotron/releases

Choose the latest version for your operating system:

  • macOS: Download the .dmg file
  • Windows: Download the .exe installer
  • Linux: Download the .AppImage or .deb file

Install and launch the app.


Step 6: Run Your App and Connect

Now for the moment of truth! Start your React Native app:

npm start
# Then press 'i' for iOS or 'a' for Android
Enter fullscreen mode Exit fullscreen mode

When your app launches, you should see:

  1. "Reactotron Configured" in your Metro console
  2. Your app name appearing in the Reactotron desktop app (usually in the top-left)

How to Inspect AsyncStorage

Once connected, inspecting AsyncStorage is easy:

Method 1: Timeline View

  1. Open Reactotron desktop app
  2. Look at the Timeline (left sidebar)
  3. You'll see all AsyncStorage operations (get, set, remove) logged in real-time

Method 2: AsyncStorage Browser

  1. Click the "AsyncStorage" button in the top toolbar
  2. You'll see a list of all keys and their values
  3. Click any key to expand and view its full content
  4. You can even edit or delete values directly!

Method 3: Custom Logs

In your code, you can send custom data to Reactotron:

import Reactotron from 'reactotron-react-native';

// Simple log
Reactotron.log('Houses loaded successfully!');

// Display structured data
Reactotron.display({
    name: 'Houses Data',
    value: houses,
    preview: `${houses.length} houses in storage`
});
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
kalama_ayubu_920a009aeba9 profile image
Kalama Ayubu

I've been trying a bunch of failed ways to see whats happening on my asyncStorage if at all anything is happening(through the operations am making), But this article was clear, precise... Great write-up Cathy

Collapse
 
cathylai profile image
Cathy Lai

I'm glad this helped! I was confused yesterday too until I figured it out.

I think sometime you have to reload the app for Reacteron to pick it up.

Also ChatGPT helped me write the articles too - it's really handy for an initial draft.

Collapse
 
kalama_ayubu_920a009aeba9 profile image
Kalama Ayubu

You seem to have some cool react native "tips and tricks"... Keep it up, and who knows maybe your next post will be exactly on the bug(s) that am encouraging 😂😂