Expo DevTools 3.0: What Changed and How to Upgrade from 2.x
Expo DevTools 3.0 is now available.
This release introduces a simpler setup API and several changes to how DevTools is initialized and integrated into Expo applications.
If you're currently using @axonpack/expo-devtools 2.x, this guide gives you a quick overview of the migration and the main changes you need to know.
What's Changed in 3.0?
The main changes include:
- A new
DevtoolsProvider-based setup - Removal of the DevTools client instance
- Changes to WebView integration
- Changes to how
devtoolsAPIs are imported - Behavioral changes around startup and crash capture
- New APIs for controlling the DevTools panel
- Removal of
webviewSources
Most existing configuration remains compatible. The network, console, performance, storage, and crash configuration fields keep the same structure.
1. A Simpler DevTools Setup
In 2.x, you had to create a DevTools client, initialize it, and mount the overlay separately.
In 3.0, this is replaced with DevtoolsProvider.
Example:
<DevtoolsProvider config={{ enabled: __DEV__ }}>
The condition you previously used to control whether DevTools was mounted can now be passed through the enabled configuration.
It doesn't have to be \_\_DEV\_\_. You can use an environment variable, a configuration value, or another condition depending on your application.
For larger configurations, you can keep the configuration in its own file:
import type { DevtoolsConfig } from '@axonpack/expo-devtools';
export const devtoolsConfig = {
enabled: __DEV__,
// ...your configuration
} satisfies DevtoolsConfig;
2. WebView Integration
WebView integration has also been simplified.
Previously, several properties had to be wired directly from the DevTools client.
In 3.0, you can use useDevtoolsWebView():
const devtoolsWebView = useDevtoolsWebView('checkout');
<WebView
{...devtoolsWebView}
source={{ uri }}
/>
The WebView name is now passed directly to the hook.
Because of this change, webviewSources should be removed from your configuration.
3. Import devtools Directly
APIs such as:
markmeasureclearMarksclearMeasuressetCrashContext- DevTools stores
keep their existing names and signatures.
The main difference is where they come from.
Instead of importing your own client instance:
import { devtools } from '../devtools';
Import it directly from the package:
import { devtools } from '@axonpack/expo-devtools';
What Moved?
| 2.x | 3.0 |
|---|---|
createDevtoolsClient(config) | <DevtoolsProvider config={config}> |
devtools.init() | Removed |
<DevtoolsOverlay /> | Integrated into <DevtoolsProvider> |
| Overlay mount condition | config.enabled |
config.webviewSources | Removed |
getWebViewRef() | useDevtoolsWebView().ref |
getWebViewUserAgent() | useDevtoolsWebView().userAgent |
handleWebViewMessage | useDevtoolsWebView().onMessage |
DevtoolsClientConfig | DevtoolsConfig |
DevtoolsOverlayProps | DevtoolsProviderProps |
Behavioral Changes
There are two important behavioral changes to be aware of.
DevTools Capture Startup
Capture now starts when the provider renders rather than when the module is evaluated.
It still starts before child components mount, so requests from the first screen are captured.
However, requests made while modules are being evaluated may happen before DevTools starts capturing them.
If you previously moved init() ahead of Expo Router's entry file to capture those requests, that workaround is no longer applicable.
Instead, let the root layout hold the provider.
Crash Capture
crash.enableWhileDevtoolsDisabled now installs at the provider's first render.
It still captures crashes when:
enabled: false
The flag continues to capture only crashes that terminate the application.
New in 3.0
useDevtoolsPanel()
You can now control the DevTools panel from your own UI:
const { open, close } = useDevtoolsPanel();
This allows you to build custom controls for opening and closing the panel.
Hide the Floating Button
If you want the panel functionality without displaying the default launcher button:
<DevtoolsProvider
config={{
enabled: __DEV__,
}}
showFloatingButton={false}
\>
The panel remains available even when the floating button is hidden.
Migration Checklist
If you're upgrading from 2.x:
- Replace
createDevtoolsClient()withDevtoolsProvider - Remove
devtools.init() - Remove the separate
DevtoolsOverlay - Move your enable/disable condition to
config.enabled - Move WebView wiring to
useDevtoolsWebView() - Remove
webviewSources - Import
devtoolsdirectly from@axonpack/expo-devtools - Review code that depended on early
init()execution - Check your crash configuration
- Consider using
useDevtoolsPanel()for custom controls
Full Upgrade Guide
I've documented the complete migration here:
https://axonpack.github.io/docs/expo-devtools/upgrading
GitHub:
https://github.com/axonpack/expo-devtools
If you're already using Expo DevTools, I'd love to hear your feedback, issues, and suggestions.