1--- 2title: Debugging runtime issues 3description: Learn about different techniques available to debug your Expo project. 4sidebar_title: Runtime issues 5--- 6 7import { BoxLink } from '~/ui/components/BoxLink'; 8import { Step } from '~/ui/components/Step'; 9import { Terminal } from '~/ui/components/Snippet'; 10import ImageSpotlight from '~/components/plugins/ImageSpotlight'; 11import { BookOpen02Icon } from '@expo/styleguide-icons'; 12 13Whether you're developing your app locally, sending it out to select beta testers, or launching your app live to the app stores, you'll always find yourself debugging issues. It's useful to split errors into two categories: 14 15- Errors you encounter in the development 16- Errors you (or your users) encounter in production 17 18Let's go through recommended practices when dealing with each of the above situations. 19 20## Development errors 21 22They are common errors that you encounter while developing your app. Delving into them isn't always straightforward. Usually, debugging when running your app with [Expo CLI](/more/expo-cli/) is enough. 23 24One way you can debug these issues is by looking at the [stack trace](/debugging/errors-and-warnings/#stack-traces). However, in some scenarios, looking at the stack trace isn't enough as the error message traced might be a little more cryptic. For such errors, follow the steps below: 25 26- Search for the error message in Google and [Stack Overflow](https://stackoverflow.com/questions), it's likely you're not the first person to ever run into this. 27- **Isolate the code that's throwing the error**. This step is _vital_ in fixing obscure errors. To do this: 28 - Revert to a working version of your code. This may even be a completely blank `npx create-expo-app` project. 29 - Apply your recent changes piece by piece, until it breaks. 30 - If the code you're adding in each "piece" is complex, you may want to simplify what you're doing. For example, if you use a state management library such as Redux, you can try removing that from the equation completely to see if the issue lies in your state management (which is common in React apps). 31 - This should narrow down the possible sources of the error, and provide you with more information to search the internet for others who have had the same problem. 32- Use breakpoints (or `console.log`s) to check and make sure a certain piece of code is being run, or that a variable has a certain value. Using `console.log` for debugging isn't considered the best practice, however, it's fast, easy, and oftentimes provides some illuminating information. 33 34Simplifying code as much as possible to track down the source of error is a great way to debug your app and it gets exponentially easier. That's why many open-source repositories require a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) when you open an issue. It ensures you have isolated the issue and identified exactly where the problem occurs. If your app is too large and complex to do that, try and extract the functionality you're trying to add in a blank `npx create-expo-app` project, and go from there. 35 36### Native debugging 37 38You can perform full native debugging with Android Studio and Xcode by generating source code locally and building from that source. 39 40#### Android Studio 41 42<Step label="1"> 43 44Generate the native code for your project by running the following command: 45 46<Terminal cmd={['$ npx expo prebuild -p android']} /> 47 48This will add an **android** directory at the root of your project. 49 50</Step> 51 52<Step label="2"> 53 54Open the project in Android Studio by running the command: 55 56<Terminal cmd={['$ open -a /Applications/Android Studio.app ./android']} /> 57 58</Step> 59 60<Step label="3"> 61 62Build the app from Android Studio and connect the debugger. See [Google's documentation](https://developer.android.com/studio/debug#startdebug) for more information. 63 64</Step> 65 66> You can delete the **android** directory when you are done with this process. This ensures that your project remains managed by Expo CLI. Keeping the directory around and manually modifying it outside of `npx expo prebuild` means you'll need to manually upgrade and configure native libraries yourself (which is bare workflow). 67 68#### Xcode 69 70> This is only available for macOS users and requires Xcode to be installed. 71 72<Step label="1"> 73 74Generate the native code for your project by running the following command: 75 76<Terminal cmd={['$ npx expo prebuild -p ios']} /> 77 78This will add an **ios** directory at the root of your project. 79 80</Step> 81 82<Step label="2"> 83 84Open the project in Xcode by running the command which is a shortcut to open the `.xcworkspace` file from your project's **ios** directory in Xcode. 85 86<Terminal cmd={['$ xed ios']} /> 87 88</Step> 89 90<Step label="3"> 91 92Build the app with <kbd>Cmd ⌘</kbd> + <kbd>r</kbd> or by pressing the play button in the upper left corner of Xcode. 93 94</Step> 95 96<Step label="4"> 97 98You can now utilize [**Low-level debugger (LLDB)**](https://developer.apple.com/library/archive/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/Introduction.html) and all of the other [Xcode debugging tools](https://developer.apple.com/documentation/metal/debugging_tools) to examine the native runtime. 99 100</Step> 101 102> You can delete the **ios** directory when you are done with this process. This ensures that your project remains managed by Expo CLI. Keeping the directory around and manually modifying it outside of `npx expo prebuild` means you'll need to manually upgrade and configure native libraries yourself (which is bare workflow). 103 104## Production errors 105 106Errors or bugs in your production app can be much harder to solve, mainly because you have less context around the error (that is, where, how, and why did the error occur?). 107 108**The best first step in addressing a production error is to reproduce it locally.** Once you reproduce an error locally, you can follow the [development debugging process](#development-errors) to isolate and address the root cause. 109 110> **Tip**: Sometimes, running your app in **production mode** locally will show errors that normally wouldn't be thrown. You can run the app locally in production by running `npx expo start --no-dev --minify`. 111> `--no-dev` tells the server not to be run in development mode, and `--minify` is used to minify your code the same way it is for production JavaScript bundles. 112 113### Production app is crashing 114 115It can be a frustrating scenario when a production app crashes. There is very little information to look into when it happens. It's important to reproduce the issue, and even if you can't do that, to find any related crash reports. 116 117Start by reproducing the crash using your production app and then **find an associated crash report**. 118 119#### Crash reports using adb logcat 120 121If your Android app is on Google Play, refer to the crashes section of the [Google Play Console](https://play.google.com/console/about/), or connect your Android device to your computer and run the following command: 122 123<Terminal cmd={['$ adb logcat']} /> 124 125The Android Debug Bridge (`adb`) program is part of the Android SDK and allows you to view streaming logs. An alternative to avoid installing Android SDK is to use [WebADB](https://webadb.com/) in Chrome. 126 127#### Crash reports using Console app 128 129If your iOS app is on TestFlight or the App Store, you can use the [Crashes Organizer](https://developer.apple.com/news/?id=nra79npr) in Xcode. 130 131If not, you can use the **Console** app in Xcode by connecting your device to your mac. Follow the steps below on how to access the Console app: 132 133<Step label="1"> 134 135Open Xcode app, and then open **Devices and Simulators** window by pressing <kbd>Shift</kbd> + <kbd>Cmd ⌘</kbd> + <kbd>2</kbd>. 136 137</Step> 138 139<Step label="2"> 140 141If you've connected a physical device, select it under **Devices**. Otherwise, if you are using a simulator, select it under **Simulators**. 142 143<ImageSpotlight 144 alt="Devices and Simulators window in Xcode." 145 src="/static/images/debugging/devices-simulators.png" 146/> 147 148</Step> 149 150<Step label="3"> 151 152Click on **Open Console** button shown in the window to open the console app. 153 154<ImageSpotlight 155 alt="Devices and Simulators window in Xcode." 156 src="/static/images/debugging/open-console.png" 157/> 158 159This will open the console app for you to view logs from your device or simulator. 160 161</Step> 162 163For more information, see Apple's [Diagnosing Issues Using Crash Reports and Device Logs](https://developer.apple.com/documentation/xcode/diagnosing-issues-using-crash-reports-and-device-logs) guide. 164 165### App crashes on certain (older) devices 166 167This might indicate that there is a performance issue. You likely need to run your app through a profiler to get a better idea of what processes are killing the app, and [React Native provides some great documentation for this](https://reactnative.dev/docs/profiling). We also recommend using [React DevTools](https://www.npmjs.com/package/react-devtools) and the included profiler, which makes it super easy to identify performance sinks in your app. 168 169## Stuck? 170 171The Expo community and the React and React Native communities are great resources for help when you get stuck. There's a good chance someone else has run into the same error as you, so make sure to read the documentation, search the [forums](https://forums.expo.dev/), [GitHub issues](https://github.com/expo/expo/issues/), and [Stack Overflow](https://stackoverflow.com/). 172 173## Next step 174 175<BoxLink 176 title="Debugging tools" 177 description="Learn about different tools available to debug runtime issues in your Expo project." 178 href="/debugging/tools" 179 Icon={BookOpen02Icon} 180/> 181