State Management
Patterns for local state, derived data, and cross-collection composition in Routier applications.
Overview
State management in Routier involves managing application state through collections, live queries, and derived data. Routier provides built-in features that make state management straightforward and efficient.
Key Concepts
Collections as State
Collections act as your primary state containers:
class AppContext extends DataStore {
users = this.collection(userSchema).proxy().create();
products = this.collection(productSchema).proxy().create();
}Live Queries
Keep UI in sync with data changes automatically:
ctx.users.subscribe().toArray((result) => {
if (result.ok === "success") {
console.log("Users:", result.data); // Automatically updates when users change
}
});Note: With .subscribe(), you must use callback-based methods (not async methods like toArrayAsync()).
Live queries reach other browser tabs, and other worker threads in Node, because change notifications travel over a BroadcastChannel. A sender cannot see who is listening on the other end of one, so by default every save publishes its changes in case another tab is subscribed.
If the process is the only one reading the database — a server, a script, a single-tab app — set crossTabSync: false on the store. Saves then skip that work whenever nothing in the current process is subscribed, which the repository benchmark measures at roughly 10% of insert time. Subscriptions within the process keep working. See Live Queries.
Change Tracking
All modifications are tracked automatically until saved:
user.name = "New Name"; // Tracked automatically
await ctx.saveChangesAsync(); // PersistedDerived State
Compute derived data from your collections:
const stats = {
totalUsers: await ctx.users.countAsync(),
activeUsers: await ctx.users.where((u) => u.isActive).countAsync(),
};Patterns
- Single Source of Truth: Collections serve as your data source
- Automatic Updates: Live queries keep UI in sync
- Explicit Persistence: Changes saved with
saveChangesAsync() - Type Safety: Full TypeScript support
Related Guides
- Live Queries - Reactive data patterns
- Views - Create read-only derived collections
- Syncing - Sync with remote sources
- Change Tracking - Understanding change tracking
- Data Manipulation - Working with your data