Introduction
New Expensify uses React Native Onyx, a custom state management library built specifically for offline-first applications. Onyx provides automatic persistence, optimistic updates, and conflict resolution out of the box.Why Onyx?
Traditional state management solutions like Redux or MobX weren’t designed for offline-first apps. Onyx solves unique challenges:- Automatic Persistence: All data is automatically saved to disk
- Optimistic Updates: UI updates immediately, syncs later
- Conflict Resolution: Built-in strategies for handling sync conflicts
- Performance: Batched updates and selective re-renders
- Type Safety: Full TypeScript support
Core Concepts
1. Onyx Keys
All data in Onyx is stored with unique keys defined insrc/ONYXKEYS.ts:
2. Onyx Methods
Reading Data with connect
Writing Data
3. Using Onyx with React
Use theuseOnyx hook (recommended):
4. Collection Keys
Collections store multiple related items:Onyx Updates in API Calls
API calls use Onyx updates to manage state:Onyx Method Types
| Method | Description | Example |
|---|---|---|
SET | Replace entire value | Reset a policy |
MERGE | Update specific fields | Update policy name |
MERGE_COLLECTION | Update multiple collection items | Bulk update reports |
ONYXKEYS Reference
Fromsrc/ONYXKEYS.ts:
Authentication & Session
User Data
Reports & Messages
Transactions
Policies (Workspaces)
Network & App State
Performance Optimization
1. Use Selectors
Selectors prevent unnecessary re-renders:2. Allow Stale Data
For performance-critical components:3. Batch Updates
Onyx automatically batches updates, but you can optimize further:4. Metadata Pattern
Separate loading states from data to prevent re-renders:Offline Behavior
Pending Actions
UsependingAction to indicate data state:
Error Handling
Store errors in Onyx:OfflineWithFeedback:
Testing with Onyx
Setup
Testing Components
Testing Actions
Best Practices
1. Always Use Typed Keys
2. Clean Up Connections
3. Use Appropriate Merge vs Set
4. Provide All Three Data Sets
For write operations, always include optimistic, success, and failure data:5. Use finallyData When Appropriate
If success and failure data are identical:Advanced Patterns
Derived Data
Compute derived values outside Onyx:Conditional Subscriptions
Debugging Onyx
Redux DevTools Integration
Enable in.env:
Logging Onyx Changes
Troubleshooting
Data Not Updating
- Check that you’re using the correct Onyx key
- Verify optimisticData/successData/failureData are set correctly
- Check network tab for API responses
- Look for errors in failureData being applied
Performance Issues
- Use selectors to prevent unnecessary re-renders
- Use
allowStaleDatafor non-critical data - Separate data and metadata into different keys
- Check for missing
React.memoon components
Next Steps
Offline-First
Learn offline-first patterns with Onyx
API Reference
Understand API integration with Onyx
Testing
Test components using Onyx
Best Practices
Follow Onyx best practices
