react-native-mmkv-storage-devtools
v0.1.0
Published
React Native DevTools panel for react-native-mmkv-storage.
Downloads
17
Maintainers
Readme
react-native-mmkv-storage-devtools
A React Native DevTools panel for react-native-mmkv-storage. Browse every instance, key, type and value while the app runs, and edit or delete entries from the panel.
Built on Rozenite, the plugin framework for React Native DevTools.
Install
npm install --save-dev react-native-mmkv-storage-devtools @rozenite/metroEnable Rozenite in Metro
const { withRozenite } = require('@rozenite/metro');
const { getDefaultConfig } = require('@react-native/metro-config');
module.exports = withRozenite(getDefaultConfig(__dirname), {
enabled: process.env.NODE_ENV !== 'production'
});Rozenite is disabled unless enabled is set, so this option is required.
Register your instances
import { MMKVLoader } from 'react-native-mmkv-storage';
import { useMMKVDevTools } from 'react-native-mmkv-storage-devtools';
const storage = new MMKVLoader().initialize();
export default function App() {
useMMKVDevTools({ storages: [storage] });
return <YourApp />;
}Instances have to be passed explicitly — the library can list instance IDs, but recreating an instance from an ID alone would not carry its encryption key or options.
Pass an object to label them yourself:
useMMKVDevTools({
storages: {
user: userStorage,
cache: cacheStorage
}
});Opening the panel
- Start Metro (
npx react-native start). Rozenite discovers plugins at startup — look for[Rozenite] Loaded 1 plugin(s)and this plugin's name in the output. - Run the app.
- Open React Native DevTools: press
jin the Metro terminal, or use the dev menu (shake, oradb shell input keyevent 82). - Select the MMKV Storage tab.
If the tab never shows up, check in this order: enabled was passed to withRozenite; Metro was restarted after installing the plugin; useMMKVDevTools is actually being called.
If the tab is present but entries never change, the instance being written to is not the one that was registered. Export the instance from a single module instead of calling MMKVLoader again where it is used — two loaders with the same ID give two handles to the same store, but only the object passed to the hook is observed.
Options
| Option | Type | Description |
| --- | --- | --- |
| storages | MMKVInstance[] \| Record<string, MMKVInstance> | Instances to inspect. An array uses each instance's instanceID as its label. |
| blacklist | RegExp | Hides matching entries. Tested against instanceId:key. |
Hide sensitive values with blacklist:
useMMKVDevTools({
storages: [storage],
blacklist: /token|password|secret/i
});Production builds
The package entry resolves to a no-op when NODE_ENV is production, so useMMKVDevTools costs nothing in release builds and no panel code is bundled. Keeping the call unguarded in your app is safe.
How updates reach the panel
The panel observes the instance's transactions — an onwrite observer per data type and one ondelete observer — using transactions.subscribe. Transactions run on every write and delete regardless of listeners, so new and removed keys appear immediately without polling.
subscribe is used instead of register on purpose: a mutator would replace whatever the app had registered for that type. Observers are additive and cannot change values, so the panel never alters the behaviour of the app it inspects.
The initial snapshot reads from the type indexes, so onread mutators do not run on it — the panel shows what is actually stored.
Editing
Click a value to edit it, then press Enter or Save. The draft is parsed according to the entry's existing type:
number— must parse as a numberboolean—trueorfalseobjectandarray— must parse as JSONstring— used as typed
An entry keeps its type. To store a different type for a key, delete it and write it again from your app.
Developing this plugin
npm install
npm run builddist/ is not checked in, so it has to be built once before the example app can load the panel. Rozenite reads plugins when Metro boots, so after every rebuild Metro must be restarted — a fast refresh will not pick up the new panel bundle.
The example app in this repo consumes the plugin from file:../packages/devtools-plugin and registers its storages in example/App.tsx.
