Quick start
Pre-requisites
If you're already familiar with JavaScript, React and React Native, then you'll be able to get moving quickly! Otherwise, it's highly recommended to get yourself familiar with these topics and then come back here:
Installation
Automatic Installation (Recommended)
The easiest way to get started is with the rozenite init
command. This command will automatically install the necessary packages and make the required configuration changes for your project.
This command will:
- Detect your bundler (Metro or Re.Pack)
- Install the appropriate Rozenite package
- Modify your bundler configuration automatically
- Set up plugin auto-discovery
If the automatic installation fails or you prefer to configure manually, follow the manual installation steps below.
Manual Installation
Choose Your Bundler
Rozenite supports both Metro and Re.Pack bundlers. Choose the package that matches your setup:
For Metro bundler (default React Native bundler):
npm install -D @rozenite/metro
For Re.Pack bundler:
npm install -D @rozenite/repack
Configuration
Rozenite integrates with your bundler configuration (Metro or Re.Pack) and requires explicit enablement through the enabled
property. This section covers how to configure Rozenite for both bundlers.
Manual Enablement Required
Rozenite is disabled by default and must be explicitly enabled by providing the enabled
configuration property in your bundler config. Without this property, Rozenite will not load any plugins or provide debugging functionality.
Metro Configuration
To enable Rozenite's auto-discovery and plugin system with Metro, you need to modify your Metro configuration and explicitly set the enabled
property. Rozenite will automatically discover and enable all installed plugins when enabled.
Important: You must manually set the enabled
property to true
(or a condition that evaluates to true
) for Rozenite to work. This ensures Rozenite only runs when you want it to.
The most common pattern is to derive this from an environment variable:
# Enable Rozenite in development
WITH_ROZENITE=true npm start
# Or disable it
WITH_ROZENITE=false npm start
This approach provides several benefits:
- Production Safety: Rozenite is automatically disabled in production builds
- Team Flexibility: Different team members can enable/disable Rozenite as needed
- CI/CD Control: Build systems can control when Rozenite is active
- Performance: Disable Rozenite when not needed to reduce overhead
Basic Configuration
Update your metro.config.js
file:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withRozenite } = require('@rozenite/metro');
const defaultConfig = getDefaultConfig(__dirname);
const customConfig = {
// Your existing Metro configuration
};
module.exports = withRozenite(mergeConfig(defaultConfig, customConfig), {
enabled: process.env.WITH_ROZENITE === 'true', // Required: Rozenite is disabled by default
});
Advanced Configuration
If you're using additional Metro plugins or configurations:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withRozenite } = require('@rozenite/metro');
const { withNxMetro } = require('@nx/react-native'); // Example with Nx
const defaultConfig = getDefaultConfig(__dirname);
const customConfig = {
// Your existing Metro configuration
};
module.exports = withRozenite(
withNxMetro(mergeConfig(defaultConfig, customConfig)),
{
enabled: process.env.WITH_ROZENITE === 'true',
}
);
Re.Pack Configuration
To enable Rozenite's auto-discovery and plugin system with Re.Pack, you need to modify your Re.Pack configuration. Rozenite integrates seamlessly with Re.Pack's DevServer.
Important: Just like with Metro, you must manually set the enabled
property to true
(or a condition that evaluates to true
) for Rozenite to work. This ensures Rozenite only runs when you want it to.
Basic Configuration
Update your rspack.config.mjs
file:
rspack.config.mjs
import { withRozenite } from '@rozenite/repack';
export default withRozenite(
{
// Your existing Re.Pack configuration
},
{
enabled: process.env.WITH_ROZENITE === 'true', // Required: Rozenite is disabled by default
}
);
With Custom Options
Configure plugin discovery and filtering:
rspack.config.mjs
import { withRozenite } from '@rozenite/repack';
export default withRozenite(
{
// Your existing Re.Pack configuration
},
{
enabled: process.env.WITH_ROZENITE === 'true',
include: ['@rozenite/mmkv-plugin', '@rozenite/network-activity-plugin'],
exclude: ['unwanted-plugin'],
destroyOnDetachPlugins: ['@rozenite/network-activity-plugin'],
}
);
Auto-Discovery
Once configured, Rozenite will automatically:
- Discover installed plugins in your
node_modules
- Enable all found plugins without manual configuration
- Load plugin panels into React Native DevTools
- Handle plugin communication between DevTools and your React Native app
Plugin Discovery
Rozenite automatically discovers plugins by looking for rozenite.json
files in the /dist
directory of packages. If a package contains this file, it's recognized as a Rozenite plugin.
Rozenite searches for plugins by crawling the entire node_modules
directory tree, starting from your project's node_modules
and traversing up to the root of the file system. This means it will find plugins in:
- Your project's
node_modules
- Parent directories'
node_modules
(if using workspaces or monorepos)
- Global
node_modules
(if any)
By default, Rozenite will automatically discover and load all plugins found in your node_modules
.
Plugin Filtering
While Rozenite automatically discovers all plugins by default, you can control which plugins are loaded using the configuration options:
Include Specific Plugins
If you want to load only specific plugins, you can use the include
option. When this option is provided, auto-discovery is disabled and only the listed plugins will be loaded:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withRozenite } = require('@rozenite/metro');
const defaultConfig = getDefaultConfig(__dirname);
const customConfig = {
// Your existing Metro configuration
};
module.exports = withRozenite(mergeConfig(defaultConfig, customConfig), {
enabled: process.env.WITH_ROZENITE === 'true',
include: ['@rozenite/mmkv-plugin', '@rozenite/network-activity-plugin'],
});
rspack.config.mjs
import { withRozenite } from '@rozenite/repack';
export default withRozenite(
{
// Your existing Re.Pack configuration
},
{
enabled: process.env.WITH_ROZENITE === 'true',
include: ['@rozenite/mmkv-plugin', '@rozenite/network-activity-plugin'],
}
);
Exclude Specific Plugins
To prevent certain plugins from loading while keeping auto-discovery enabled, use the exclude
option:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withRozenite } = require('@rozenite/metro');
const defaultConfig = getDefaultConfig(__dirname);
const customConfig = {
// Your existing Metro configuration
};
module.exports = withRozenite(mergeConfig(defaultConfig, customConfig), {
enabled: process.env.WITH_ROZENITE === 'true',
exclude: ['@rozenite/mmkv-plugin'],
});
rspack.config.mjs
import { withRozenite } from '@rozenite/repack';
export default withRozenite(
{
// Your existing Re.Pack configuration
},
{
enabled: process.env.WITH_ROZENITE === 'true',
exclude: ['@rozenite/mmkv-plugin'],
}
);
Combining Include and Exclude
You can also combine both options. When both are provided, the exclude
list is applied to the include
list:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withRozenite } = require('@rozenite/metro');
const defaultConfig = getDefaultConfig(__dirname);
const customConfig = {
// Your existing Metro configuration
};
module.exports = withRozenite(mergeConfig(defaultConfig, customConfig), {
enabled: process.env.WITH_ROZENITE === 'true',
include: [
'@rozenite/mmkv-plugin',
'@rozenite/network-activity-plugin',
'@rozenite/tanstack-query-plugin',
],
exclude: ['@rozenite/mmkv-plugin'], // This will be filtered out from the include list
});
rspack.config.mjs
import { withRozenite } from '@rozenite/repack';
export default withRozenite(
{
// Your existing Re.Pack configuration
},
{
enabled: process.env.WITH_ROZENITE === 'true',
include: [
'@rozenite/mmkv-plugin',
'@rozenite/network-activity-plugin',
'@rozenite/tanstack-query-plugin',
],
exclude: ['@rozenite/mmkv-plugin'], // This will be filtered out from the include list
}
);
Note: When using the include
option, auto-discovery is completely disabled. Only the explicitly listed plugins will be loaded, and any plugins not in the list will be ignored, even if they are installed in your node_modules
.
Plugin State Management
By default, Rozenite preserves plugin UI state when switching between DevTools panels. This provides a smooth user experience where data doesn't get lost when navigating between different plugins. However, for plugins that consume significant memory or resources, you may want to destroy them when they're not active.
Configuring Plugin Destruction
Use the destroyOnDetachPlugins
option to specify which plugins should be destroyed when switching panels:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withRozenite } = require('@rozenite/metro');
const defaultConfig = getDefaultConfig(__dirname);
const customConfig = {
// Your existing Metro configuration
};
module.exports = withRozenite(mergeConfig(defaultConfig, customConfig), {
enabled: process.env.WITH_ROZENITE === 'true',
destroyOnDetachPlugins: [
'@rozenite/network-activity-plugin',
'@rozenite/tanstack-query-plugin',
],
});
rspack.config.mjs
import { withRozenite } from '@rozenite/repack';
export default withRozenite(
{
// Your existing Re.Pack configuration
},
{
enabled: process.env.WITH_ROZENITE === 'true',
destroyOnDetachPlugins: [
'@rozenite/network-activity-plugin',
'@rozenite/tanstack-query-plugin',
],
}
);
Trade-offs when using this option:
- Lost state - Plugin state is reset every time you switch to another panel
- Slower navigation - Plugin needs to reinitialize when switching back
Usage
After configuration, start your development server as usual:
Rozenite will automatically load and enable all discovered plugins. You can verify this by checking your bundler server logs for plugin discovery messages.
Verification
To verify that Rozenite is working correctly:
- Check bundler logs - You should see plugin discovery messages in Metro or Re.Pack server logs
- Open React Native DevTools - Your app should show additional panels from discovered plugins
- Check Chrome DevTools - Open Chrome DevTools within the React Native DevTools window (DevTools inception!) and look for Rozenite logs in the console