storage package

Storage browser and monitoring tool for React Native development. Supports both AsyncStorage and MMKV.
- Storage Browser: Browse all AsyncStorage and MMKV keys and values
- MMKV Support: Monitor and debug MMKV instances (including encrypted storage)
- Multiple Storage Types: Support for AsyncStorage, MMKV, and multiple MMKV instances
- Live Event Monitoring: Track all storage operations in real-time
- Edit & Delete: Modify or remove storage items directly
- Add New Items: Create new storage entries
- Required Key Validation: Define and validate required storage keys
- Type Checking: Validate storage value types
- Value Validation: Check if values match expected patterns
- Search & Filter: Search through keys and filter by status
- Copy Functionality: Easily copy keys and values
- Beautiful UI: Modern, game-themed interface matching other React Buoy tools
This package is part of the React Buoy monorepo and is automatically available to other packages and the example app.
For external projects:
``bashRequired: Core storage package and AsyncStorage
npm install @react-buoy/storage @react-native-async-storage/async-storage
Or with pnpm/yarn:
`bash
Required
pnpm add @react-buoy/storage @react-native-async-storage/async-storageOptional: MMKV support
pnpm add react-native-mmkv
`Quick Start
$3
Import the preset and add it to your tools array. Done!
`typescript
import { storageToolPreset } from '@react-buoy/storage';
import { FloatingDevTools } from '@react-buoy/core';const installedApps = [
storageToolPreset, // That's it! One line.
// ...your other tools
];
function App() {
return (
apps={installedApps}
environment="local"
userRole="admin"
/>
);
}
`Done! The preset automatically:
- ✅ Browses all AsyncStorage keys
- ✅ Monitors storage operations
- ✅ Provides edit/delete/add functionality
- ✅ No configuration required
$3
If you need to validate specific storage keys:
`typescript
import { createStorageTool } from '@react-buoy/storage';const requiredStorageKeys = [
{
key: "@app/session",
expectedType: "string",
description: "User session token",
storageType: "async",
},
{
key: "@app/settings:theme",
expectedValue: "dark",
description: "Preferred theme",
storageType: "async",
},
];
const myStorageTool = createStorageTool({
requiredStorageKeys,
colorPreset: "purple",
enableSharedModalDimensions: true,
});
const installedApps = [
myStorageTool,
// ...other tools
];
`$3
If you're not using FloatingDevTools or want more control:
`typescript
import { StorageModalWithTabs } from '@react-buoy/storage';const requiredStorageKeys = [
{
key: "@app/session",
expectedType: "string",
description: "User session token",
storageType: "async",
},
];
function App() {
const [showStorage, setShowStorage] = useState(false);
return (
<>
visible={showStorage}
onClose={() => setShowStorage(false)}
requiredStorageKeys={requiredStorageKeys}
/>
>
);
}
`MMKV Support
React Buoy Storage fully supports react-native-mmkv, a fast, efficient storage solution for React Native.
$3
- 10x faster than AsyncStorage
- Synchronous API - no async/await needed
- Encryption support - built-in AES encryption
- Multi-process support - share data between extensions
- Small bundle size - ~30KB
$3
⚠️ IMPORTANT: Manual registration is required for MMKV v4. Auto-detection is not possible due to Metro bundler and ES6 module limitations.
You must call
registerMMKVInstance() for each MMKV instance you want to monitor in the DevTools.$3
`typescript
import { createMMKV } from 'react-native-mmkv';
import { registerMMKVInstance } from '@react-buoy/storage';// 1. Create your MMKV instance
export const storage = createMMKV({
id: 'mmkv.default'
});
// 2. Register it with DevTools (required!)
registerMMKVInstance('mmkv.default', storage);
`That's it! Your MMKV instance is now visible in the Storage DevTools.
$3
`typescript
import { createMMKV } from 'react-native-mmkv';
import { registerMMKVInstance } from '@react-buoy/storage';// Create encrypted instance
export const secureStorage = createMMKV({
id: 'secure-storage',
encryptionKey: 'my-encryption-key'
});
// Register with encrypted flag
registerMMKVInstance('secure-storage', secureStorage, {
encrypted: true
});
`$3
You can create and monitor multiple MMKV instances for different purposes:
`typescript
import { createMMKV } from 'react-native-mmkv';
import { registerMMKVInstance } from '@react-buoy/storage';// User preferences
export const userPrefs = createMMKV({ id: 'user-prefs' });
registerMMKVInstance('user-prefs', userPrefs);
// API cache
export const apiCache = createMMKV({ id: 'api-cache' });
registerMMKVInstance('api-cache', apiCache);
// Secure auth storage
export const authStorage = createMMKV({
id: 'auth',
encryptionKey: process.env.ENCRYPTION_KEY
});
registerMMKVInstance('auth', authStorage, { encrypted: true });
`$3
Once registered, MMKV instances automatically appear in the Storage Browser:
`typescript
import { FloatingDevTools } from '@react-buoy/core';
import { storageToolPreset } from '@react-buoy/storage';
import './mmkv-setup'; // Import your MMKV setup filefunction App() {
return (
apps={[storageToolPreset]}
environment="local"
userRole="admin"
/>
);
}
`The Storage Browser will show:
- All your MMKV instances (default, user-prefs, api-cache, auth, etc.)
- All AsyncStorage keys
- Real-time updates when data changes
- Ability to edit, delete, and add keys
$3
####
registerMMKVInstance(id, instance, config?)Register an MMKV instance with DevTools for monitoring and debugging.
Parameters:
-
id (string) - Unique identifier for this instance (should match the id used in createMMKV)
- instance (MMKV) - The MMKV instance returned from createMMKV()
- config (optional) - Configuration object
- encrypted (boolean) - Set to true if instance uses encryptionReturns:
voidExample:
`typescript
import { createMMKV } from 'react-native-mmkv';
import { registerMMKVInstance } from '@react-buoy/storage';const storage = createMMKV({ id: 'my-storage' });
registerMMKVInstance('my-storage', storage);
`####
unregisterMMKVInstance(id)Unregister an MMKV instance from DevTools monitoring. Typically not needed unless you're dynamically creating/destroying instances.
Parameters:
-
id (string) - The instance ID to unregisterReturns:
voidExample:
`typescript
import { unregisterMMKVInstance } from '@react-buoy/storage';unregisterMMKVInstance('my-storage');
`$3
Auto-detection is fundamentally impossible for MMKV v4 due to:
1. ES6 Module Exports are Sealed - Cannot monkey-patch
createMMKV function
2. Metro Bundler Limitations - No access to require.cache or module interception
3. Nitro Modules Architecture - MMKV instances created in native C++ layerManual registration is a simple one-line call per instance and provides explicit control over what's monitored.
$3
Recommended structure:
`typescript
// utils/storage.ts
import { createMMKV } from 'react-native-mmkv';
import { registerMMKVInstance } from '@react-buoy/storage';export const storage = createMMKV({ id: 'mmkv.default' });
export const secureStorage = createMMKV({
id: 'secure',
encryptionKey: 'your-key'
});
if (__DEV__) {
registerMMKVInstance('mmkv.default', storage);
registerMMKVInstance('secure', secureStorage, { encrypted: true });
}
`Then import in your app:
`typescript
import { storage, secureStorage } from './utils/storage';// Use anywhere in your app
storage.set('user.name', 'John Doe');
secureStorage.set('auth.token', 'secret-token');
`API Reference
$3
####
storageToolPresetPre-configured AsyncStorage browser tool ready to use with FloatingDevTools.
Example:
`typescript
import { storageToolPreset } from '@react-buoy/storage';const installedApps = [storageToolPreset];
`####
createStorageTool(options?)Create a custom AsyncStorage browser tool configuration.
Options:
`typescript
{
/* Tool name (default: "STORAGE") /
name?: string;
/* Tool description /
description?: string;
/* Icon color preset (default: "green") /
colorPreset?: "orange" | "cyan" | "purple" | "pink" | "yellow" | "green";
/* Custom tool ID (default: "storage") /
id?: string;
/* Array of required storage keys to validate /
requiredStorageKeys?: RequiredStorageKey[];
/* Enable shared modal dimensions /
enableSharedModalDimensions?: boolean;
}
`Example:
`typescript
import { createStorageTool } from '@react-buoy/storage';const requiredStorageKeys = [
{
key: "@app/session",
expectedType: "string",
description: "User session token",
storageType: "async",
},
];
const myStorageTool = createStorageTool({
name: "APP STORAGE",
requiredStorageKeys,
colorPreset: "cyan",
enableSharedModalDimensions: true,
});
`$3
####
StorageModalWithTabsMain modal component with two tabs: Browser and Events.
Props:
`typescript
interface StorageModalWithTabsProps {
/* Whether the modal is visible /
visible: boolean;
/* Callback when modal is closed /
onClose: () => void;
/* Optional back button handler /
onBack?: () => void;
/* Whether to use shared modal dimensions /
enableSharedModalDimensions?: boolean;
/* Array of required storage keys to validate /
requiredStorageKeys?: RequiredStorageKey[];
}
`Example:
`typescript
visible={isVisible}
onClose={handleClose}
requiredStorageKeys={requiredKeys}
enableSharedModalDimensions={true}
/>
`$3
####
RequiredStorageKey`typescript
interface RequiredStorageKey {
/* Storage key to validate /
key: string;
/* Optional description of the key /
description?: string;
/* Expected value type /
expectedType?: "string" | "number" | "boolean" | "object" | "array";
/* Expected value /
expectedValue?: any;
/* Storage type: "async" for AsyncStorage, "mmkv" for MMKV, "secure" for Secure Storage /
storageType: "async" | "mmkv" | "secure";
/* Whether the key is required /
required?: boolean;
}
`####
AsyncStorageEvent`typescript
interface AsyncStorageEvent {
/* Unique event ID /
id: string;
/* Event type (set, get, remove, clear, etc.) /
type: "set" | "get" | "remove" | "clear" | "multiGet" | "multiSet" | "multiRemove";
/* Storage key(s) involved /
key?: string | string[];
/* Value (for set operations) /
value?: any;
/* Timestamp of the event /
timestamp: number;
/* Whether the operation succeeded /
success: boolean;
/* Error message if operation failed /
error?: string;
}
`Use Cases
$3
Monitor and validate user session storage:
`typescript
import { createStorageTool } from '@react-buoy/storage';const requiredStorageKeys = [
{
key: "@app/session:token",
expectedType: "string",
description: "JWT auth token",
storageType: "async",
required: true,
},
{
key: "@app/session:userId",
expectedType: "string",
description: "Current user ID",
storageType: "async",
required: true,
},
];
const storageTool = createStorageTool({ requiredStorageKeys });
`$3
Validate app configuration storage:
`typescript
const requiredStorageKeys = [
{
key: "@app/settings:theme",
expectedValue: "dark",
description: "UI theme preference",
storageType: "async",
},
{
key: "@app/settings:notifications",
expectedType: "boolean",
description: "Notifications enabled",
storageType: "async",
},
{
key: "@app/settings:language",
expectedType: "string",
description: "User language preference",
storageType: "async",
},
];
`$3
Monitor cached data:
`typescript
const requiredStorageKeys = [
{
key: "@app/cache:userData",
expectedType: "object",
description: "Cached user profile data",
storageType: "async",
},
{
key: "@app/cache:timestamp",
expectedType: "number",
description: "Cache timestamp",
storageType: "async",
},
];
`Features in Detail
$3
- View All Keys: See all AsyncStorage keys and their values
- Search: Search through keys by name
- Filter: Filter by validation status (all, missing, issues)
- Edit: Modify existing values directly
- Delete: Remove storage entries
- Add: Create new storage entries
- Copy: Copy keys and values to clipboard
- Validation: See which required keys are missing or invalid
$3
- Live Monitoring: Watch all storage operations in real-time
- Event Types: Track set, get, remove, clear, and multi-operations
- Filtering: Filter events by type or key
- Search: Search through event history
- Timeline: See chronological order of operations
- Pause/Resume: Control event capture
- Clear: Clear event history
$3
Required storage keys can be validated for:
- Existence: Check if the key exists
- Type: Validate the value type (string, number, boolean, object, array)
- Value: Check if the value matches an expected value
- Custom Validation: Implement custom validation logic
Dependencies
-
@react-buoy/shared-ui - Common UI components and utilities
- @react-native-async-storage/async-storage - AsyncStorage implementation (peer dependency)
- react-native-mmkv - MMKV storage implementation (optional peer dependency)
- React and React Native (peer dependencies)Development
$3
`bash
pnpm build
`$3
`bash
pnpm typecheck
`$3
`bash
pnpm clean
``MIT
See the main repository CONTRIBUTING.md for contribution guidelines.
For issues and feature requests, please visit the GitHub repository.