{"id":26163,"library":"react-native-onyx","title":"react-native-onyx","description":"Persistent state management library for React Native, wrapping pub/sub patterns around AsyncStorage-like backends. Current version 3.0.71, active development, with frequent releases. Key differentiators: automatic persistent storage, collection-oriented key design (e.g., report_1234), React hooks (useOnyx) and non-React subscribers (Onyx.connect). Requires idb-keyval, react-native-device-info, react-native-nitro-modules, and react-native-nitro-sqlite as peer dependencies. Ships TypeScript definitions, supports browser bundling via Webpack. Unlike Redux or MobX, Onyx is tailored for React Native's offline-first, persistent-storage needs with minimal boilerplate.","status":"active","version":"3.0.71","language":"javascript","source_language":"en","source_url":"https://github.com/Expensify/react-native-onyx","tags":["javascript","React Native","React","Persistent storage","Pub/Sub","typescript"],"install":[{"cmd":"npm install react-native-onyx","lang":"bash","label":"npm"},{"cmd":"yarn add react-native-onyx","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-native-onyx","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"IndexedDB key-value store for web/browser fallback","package":"idb-keyval","optional":false},{"reason":"Device information for storage key derivation","package":"react-native-device-info","optional":false},{"reason":"Native modules bridge for SQLite backend","package":"react-native-nitro-modules","optional":false},{"reason":"SQLite backend for persistent storage on native","package":"react-native-nitro-sqlite","optional":false}],"imports":[{"note":"Default import is ESM-only. CJS require will fail due to ESM-first packaging.","wrong":"const Onyx = require('react-native-onyx')","symbol":"default","correct":"import Onyx from 'react-native-onyx'"},{"note":"Named export for React hook. TypeScript: import { useOnyx } from 'react-native-onyx' works directly.","symbol":"useOnyx","correct":"import { useOnyx } from 'react-native-onyx'"},{"note":"connect is only available as a method on the default import, not a named export.","wrong":"import { connect } from 'react-native-onyx'","symbol":"Onyx.connect","correct":"import Onyx from 'react-native-onyx'; Onyx.connect({key: 'foo', callback: ...})"}],"quickstart":{"code":"import Onyx from 'react-native-onyx';\nimport { useOnyx } from 'react-native-onyx';\n\n// Define keys\nconst ONYXKEYS = {\n    SESSION: 'session',\n    COLLECTION: { REPORT: 'report_' },\n};\n\n// Initialization\nOnyx.init({ keys: ONYXKEYS });\n\n// Setting data\nOnyx.set(ONYXKEYS.SESSION, { token: 'abc123' });\n\n// Merging data\nOnyx.merge(ONYXKEYS.SESSION, { email: 'user@example.com' });\n\n// In a React component\nfunction SessionInfo() {\n    const [session] = useOnyx(ONYXKEYS.SESSION);\n    return <Text>{session?.email}</Text>;\n}","lang":"typescript","description":"Shows full Onyx setup: import, init, set, merge, and useOnyx hook in a React component."},"warnings":[{"fix":"npm install react-native-onyx@latest idb-keyval react-native-device-info react-native-nitro-modules react-native-nitro-sqlite","message":"Version 3.0+ drops AsyncStorage and requires idb-keyval, react-native-nitro-modules, and react-native-nitro-sqlite peer deps.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Name non-collection keys without underscore, e.g., 'reportData' instead of 'report_data'","message":"Object keys must not contain the collection separator '_' unless they are part of a collection. Using 'report_123' collides with ONYXKEYS.COLLECTION.REPORT pattern.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"const current = await Onyx.get(KEY); const updated = [...current, newItem]; Onyx.set(KEY, updated);","message":"Onyx.set with an array replaces the entire array; Onyx.merge with array also replaces (unexpected). To append, read current value first and merge manually.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"const value = await Onyx.get(KEY);","message":"Onyx.get() is synchronous in v2 but asynchronous in v3 (returns Promise).","severity":"deprecated","affected_versions":">=3.0.0"},{"fix":"Onyx.init({ keys: { ... } });","message":"In v3, Onyx.init requires 'keys' config; previously it was optional. Missing keys causes runtime error.","severity":"breaking","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Ensure react-native-onyx is installed: npm install react-native-onyx. For TS, add to tsconfig.json: \"moduleResolution\": \"node\" or \"bundler\"","cause":"TypeScript project missing @types/react-native-onyx or old resolution","error":"Cannot find module 'react-native-onyx' or its corresponding type declarations."},{"fix":"Use default import: import Onyx from 'react-native-onyx'","cause":"Importing Onyx as a named export instead of default (e.g., import { Onyx } from 'react-native-onyx')","error":"TypeError: Onyx.init is not a function"},{"fix":"Use Onyx.set for primitive values, or wrap in an object: Onyx.merge(KEY, { value: 'string' })","cause":"Calling Onyx.merge with a string or number","error":"Onyx.merge only works with objects or arrays, not primitives"},{"fix":"Ensure Onyx.init is called before any Onyx.connect, and that the key exists in storage or has been set","cause":"Misunderstood init and connect order – Onyx.connect will callback with current data only after Onyx.init is called","error":"Onyx.connect callback is not called for existing data"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}