{"_id":"rozenite-zustand-devtools","_rev":"3-bce3e01502b1967f08ceb0675c9601a9","name":"rozenite-zustand-devtools","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"rozenite-zustand-devtools","version":"1.0.0","keywords":["react-native","devtools","zustand","plugin","rozenite","state-management","inspector"],"author":{"name":"IronTony"},"license":"MIT","_id":"rozenite-zustand-devtools@1.0.0","maintainers":[{"name":"irontony","email":"zimzum4@gmail.com"}],"homepage":"https://github.com/IronTony/rozenite-zustand-devtools#readme","bugs":{"url":"https://github.com/IronTony/rozenite-zustand-devtools/issues"},"dist":{"shasum":"348485bea4da62726cd9f4d8d3a379f5fd30bc73","tarball":"https://registry.npmjs.org/rozenite-zustand-devtools/-/rozenite-zustand-devtools-1.0.0.tgz","fileCount":28,"integrity":"sha512-HuEm6KoQdQOG/RgXrG7U63tWZ9PygZQ8JB4uVPfD/tOMxqhhHr7oAzmV518/C4Koc2OBFnadpZyRBb+IKpUhfQ==","signatures":[{"sig":"MEQCIF1sw2zAhQka6+imtJ1ZKq3ZwwkXEQWMlZMnbryS2QR0AiAQ1WnPLwa+fjz9JedNDXe2zKYs6ebGG0D8OW/KLKEToQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":314445},"main":"./dist/react-native.cjs","types":"./dist/react-native.d.ts","module":"./dist/react-native.js","gitHead":"2a7befb2d39ad882249b457df3a9ab840c09b8e8","scripts":{"build":"rozenite build","prepare":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"irontony","email":"zimzum4@gmail.com"},"repository":{"url":"git+https://github.com/IronTony/rozenite-zustand-devtools.git","type":"git"},"_npmVersion":"10.9.4","description":"Rozenite DevTools plugin for inspecting Zustand store state in React Native apps","directories":{},"_nodeVersion":"22.21.1","dependencies":{"@rozenite/plugin-bridge":"^1.3.0"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.18.0","vite":"^7.3.1","react":"19.0.0","rozenite":"^1.3.0","react-dom":"19.0.0","typescript":"~5.8.3","@types/react":"~19.0.0","react-native":"0.79.6","react-native-web":"^0.21.2","@rozenite/vite-plugin":"^1.3.0"},"peerDependencies":{"react":"*","react-native":"*"},"_npmOperationalInternal":{"tmp":"tmp/rozenite-zustand-devtools_1.0.0_1771864379913_0.07412372758571384","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"rozenite-zustand-devtools","version":"1.0.1","keywords":["react-native","devtools","zustand","plugin","rozenite","state-management","inspector"],"author":{"name":"IronTony"},"license":"MIT","_id":"rozenite-zustand-devtools@1.0.1","maintainers":[{"name":"irontony","email":"zimzum4@gmail.com"}],"homepage":"https://github.com/IronTony/rozenite-zustand-devtools#readme","bugs":{"url":"https://github.com/IronTony/rozenite-zustand-devtools/issues"},"dist":{"shasum":"0710fb537b00acdc85d4516da45b462fffc19aa8","tarball":"https://registry.npmjs.org/rozenite-zustand-devtools/-/rozenite-zustand-devtools-1.0.1.tgz","fileCount":28,"integrity":"sha512-tbXsnjWxnokDogCap/EUPbOxbPldkPLQ6cyk+abkb5ZMvN3LUyEYX2A1QJ71DyuJqfmQkXhIkFVtMdeyvTqCnA==","signatures":[{"sig":"MEQCICcGRDCLYruYz6rSBVhEM2Pwn4CmCJRXUaU4iXFCH/qnAiBtdGmuYO3mwgDjczvUkCeXqUc94H5QokJ71L2wjQiCaw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/rozenite-zustand-devtools@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":314419},"main":"./dist/react-native.cjs","types":"./dist/react-native.d.ts","module":"./dist/react-native.js","gitHead":"b332aaa24db96941d6782b2a7b277eaa6b86f113","scripts":{"build":"rozenite build","prepare":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2ce878c7-d1a2-4081-956c-da1cdc336446"}},"repository":{"url":"git+https://github.com/IronTony/rozenite-zustand-devtools.git","type":"git"},"_npmVersion":"11.11.0","description":"Rozenite DevTools plugin for inspecting Zustand store state in React Native apps","directories":{},"_nodeVersion":"22.22.0","dependencies":{"@rozenite/plugin-bridge":"^1.3.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","react":"19.0.0","rozenite":"^1.3.0","react-dom":"19.0.0","typescript":"~5.8.3","@types/react":"~19.0.0","react-native":"0.79.6","react-native-web":"^0.21.2","@rozenite/vite-plugin":"^1.3.0"},"peerDependencies":{"react":"*","react-native":"*"},"_npmOperationalInternal":{"tmp":"tmp/rozenite-zustand-devtools_1.0.1_1772480514468_0.8095138183747232","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"rozenite-zustand-devtools","version":"1.0.2","description":"Rozenite DevTools plugin for inspecting Zustand store state in React Native apps","license":"MIT","author":{"name":"IronTony"},"keywords":["react-native","devtools","zustand","plugin","rozenite","state-management","inspector"],"repository":{"type":"git","url":"git+https://github.com/IronTony/rozenite-zustand-devtools.git"},"homepage":"https://github.com/IronTony/rozenite-zustand-devtools#readme","bugs":{"url":"https://github.com/IronTony/rozenite-zustand-devtools/issues"},"main":"./dist/react-native.cjs","module":"./dist/react-native.js","types":"./dist/react-native.d.ts","scripts":{"build":"rozenite build","prepare":"npm run build","prepublishOnly":"npm run build"},"dependencies":{"@rozenite/plugin-bridge":"^1.3.0"},"devDependencies":{"@rozenite/vite-plugin":"^1.3.0","@types/react":"~19.0.0","react":"19.0.0","react-dom":"19.0.0","react-native":"0.79.6","react-native-web":"^0.21.2","rozenite":"^1.3.0","typescript":"~5.8.3","vite":"^7.3.1"},"peerDependencies":{"react":"*","react-native":"*"},"gitHead":"f4e8e0efcd757ade2db541b3581a826da7198b12","_id":"rozenite-zustand-devtools@1.0.2","_nodeVersion":"22.22.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-iQioMKBVpNr8ew6b7fnMKfQ/FYAlLHhekbcOUdOyjZn5zAT/5fLY8tpgC1nSDDyduGp63UnzvMH8dp5zgiaUMA==","shasum":"eb8ec48333401f555aa5dfed20143bb0087f4886","tarball":"https://registry.npmjs.org/rozenite-zustand-devtools/-/rozenite-zustand-devtools-1.0.2.tgz","fileCount":28,"unpackedSize":314419,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/rozenite-zustand-devtools@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIArAjRZ8eIGRRhi+r5QLHDS6ZUF6MDxPGfD06ju4o5nRAiEAopv0v55aZ31CBCWOHU2hydeps0J2I4FtMRYRSwR9APw="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2ce878c7-d1a2-4081-956c-da1cdc336446"}},"directories":{},"maintainers":[{"name":"irontony","email":"zimzum4@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rozenite-zustand-devtools_1.0.2_1772489531245_0.12867252221217584"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-23T16:32:59.822Z","modified":"2026-03-02T22:12:11.742Z","1.0.0":"2026-02-23T16:33:00.058Z","1.0.1":"2026-03-02T19:41:54.615Z","1.0.2":"2026-03-02T22:12:11.461Z"},"bugs":{"url":"https://github.com/IronTony/rozenite-zustand-devtools/issues"},"author":{"name":"IronTony"},"license":"MIT","homepage":"https://github.com/IronTony/rozenite-zustand-devtools#readme","keywords":["react-native","devtools","zustand","plugin","rozenite","state-management","inspector"],"repository":{"type":"git","url":"git+https://github.com/IronTony/rozenite-zustand-devtools.git"},"description":"Rozenite DevTools plugin for inspecting Zustand store state in React Native apps","maintainers":[{"name":"irontony","email":"zimzum4@gmail.com"}],"readme":"<p align=\"center\">\n  <img src=\"docs/img/banner-dark.svg\" alt=\"rozenite-zustand-devtools\" />\n</p>\n\n# rozenite-zustand-devtools\n\nA [Rozenite](https://github.com/callstackincubator/rozenite) DevTools plugin for inspecting [Zustand](https://github.com/pmndrs/zustand) store state in React Native apps.\n\nBrowse, search, and inspect all your Zustand stores in real time directly from the Rozenite DevTools panel; no middleware or store modifications required.\n\n## Features\n\n- **Real-time state inspection**: See live updates as your Zustand stores change\n- **Table & JSON views**: Toggle between a structured key-value table and raw JSON\n- **Collapsible nested objects**: Expand/collapse objects and arrays in table view\n- **Color-coded values**: Strings (green), numbers (blue), booleans (purple), null/undefined (gray)\n- **Store filtering**: Quickly find stores by name when you have many registered\n- **Copy to clipboard**: One-click copy of any store's state as formatted JSON\n- **Last updated timestamps**: See when each store was last modified\n- **Auto-select on load**: First store is selected automatically when the panel opens\n- **Zero store modifications**: Works with any Zustand store out of the box via `getState()` and `subscribe()`\n- **Debounced updates**: Uses `requestAnimationFrame` to batch rapid state changes and avoid flooding the bridge\n- **Production-safe**: The hook is replaced with a no-op in production builds, so no devtools code ships to users\n\n## Prerequisites\n\n- [Rozenite](https://github.com/callstackincubator/rozenite) integrated in your React Native project\n- [Zustand](https://github.com/pmndrs/zustand) for state management\n\n## Installation\n\n```bash\nnpm install -D rozenite-zustand-devtools\n```\n\n## Setup\n\n### 1. Define your stores\n\nCreate a file to list the Zustand stores you want to inspect (e.g., `services/zustand/devtools.ts`):\n\n```typescript\nimport type { StoreEntry } from 'rozenite-zustand-devtools';\nimport { useMyStore } from './myStore';\nimport { useAuthStore } from './authStore';\n\nexport const zustandStores: StoreEntry[] = [\n  { name: 'myStore', store: useMyStore },\n  { name: 'auth', store: useAuthStore },\n];\n```\n\n### 2. Call the hook in your root component\n\nAdd `useZustandDevTools` in your root layout or `App.tsx`, alongside your other Rozenite hooks:\n\n```tsx\nimport { useZustandDevTools } from 'rozenite-zustand-devtools';\nimport { zustandStores } from './services/zustand/devtools';\n\nexport default function Layout() {\n  // Safe to call unconditionally - no-ops in production\n  useZustandDevTools(zustandStores);\n\n  return <>{/* ... */}</>;\n}\n```\n\n### 3. Start with Rozenite enabled\n\n```bash\nWITH_ROZENITE=true npx expo start -c\n```\n\nOpen the Rozenite DevTools and you'll see a **Zustand** tab with all your registered stores.\n\n## How It Works\n\nThe plugin has two parts that communicate over Rozenite's WebSocket bridge:\n\n### React Native side (runs in your app)\n\nThe `useZustandDevTools` hook:\n\n1. Connects to the Rozenite DevTools host via `useRozeniteDevToolsClient` from `@rozenite/plugin-bridge`\n2. Sends an initial snapshot of all stores on mount\n3. Subscribes to each Zustand store using the standard `.subscribe()` API\n4. On any state change, serializes the store state (excluding functions) and sends it to the DevTools panel\n5. Responds to snapshot requests from the panel with the full state of all stores\n6. Debounces updates using `requestAnimationFrame` to prevent bridge flooding during rapid state changes\n7. Cleans up all subscriptions on unmount\n\n### DevTools panel (runs in the browser)\n\nThe panel renders inside the Rozenite DevTools as an iframe and:\n\n1. Requests a full snapshot of all stores on mount\n2. Listens for incremental `store-update` events as state changes\n3. Displays stores in a two-column layout: store list on the left, state inspector on the right\n4. Supports both **Table view** (structured key-value with collapsible nesting) and **JSON view** (raw formatted JSON)\n\n### Communication events\n\n| Event | Direction | Description |\n|-------|-----------|-------------|\n| `zustand:request-snapshot` | Panel -> App | Panel requests current state of all stores |\n| `zustand:snapshot` | App -> Panel | Full state snapshot of all registered stores |\n| `zustand:store-update` | App -> Panel | Incremental update for a single store |\n\n## API\n\n### `useZustandDevTools(stores: StoreEntry[])`\n\nReact hook that connects to the Rozenite DevTools and sends live Zustand state updates. Safe to call unconditionally - in production, the hook is replaced with a no-op at the entry-point level, so no devtools code is bundled.\n\n- **stores**: Array of stores to register\n\n```typescript\ntype StoreEntry = {\n  name: string;\n  store: {\n    getState: () => object;\n    subscribe: (listener: () => void) => () => void;\n  };\n};\n```\n\nAny Zustand store created with `create()` satisfies the `store` interface, no wrappers needed. The `name` is what appears in the DevTools sidebar.\n\n## Compatibility\n\n| Dependency | Version |\n|------------|---------|\n| Rozenite | >= 1.3.0 |\n| Zustand | Any version (uses standard `getState`/`subscribe` API) |\n| React Native | >= 0.70 |\n| React | >= 18 |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}