How LiveStore handles offline automatically
When a user commits an event, LiveStore:- Writes the event to the local SQLite store immediately
- Applies materializers to update the local state tables
- Queues the event for sync with the backend
- When connectivity is available, pushes the queued events
Making your app fully offline-capable may require additional steps beyond LiveStore’s built-in sync handling — for example, caching static assets with service workers and ensuring any external APIs you call are either optional or cached locally.
Optimistic updates
All updates in LiveStore are inherently optimistic. When you callstore.commit(event), the state table is updated immediately in the local SQLite database. There is no loading state for writes, and no separate “optimistic update” API to learn.
This differs from approaches where you update a server and then refresh local state. In LiveStore, the local event log is the source of truth and the server is a sync target.
Event queue: pending events persist locally
Committed events that have not yet synced are stored in the local event log. If the user closes the app or loses connectivity, no data is lost — the events remain queued and are sent as soon as connectivity returns. This means:- Users can work offline for hours or days and their work is never lost
- Reopening the app after a crash still has all pending events in the queue
- The sync backend does not need to be available at commit time
What happens when connectivity returns
When the sync backend becomes reachable again, LiveStore:- Pushes any locally-committed events that were not yet synced
- Pulls any events that were committed by other clients while offline
- Rebases local events on top of the remote event log if necessary
Tracking sync status
Usestore.networkStatus to observe the current connectivity state and react to changes.
Reading current status
Subscribing to changes
changes stream emits every time the sync backend connection changes. Dispose of the subscription using the Effect scope you manage for your runtime.
DevTools latch simulation
When you use DevTools to simulate an offline state,status.devtools.latchClosed is true. This lets you distinguish between a real network outage and a simulated one in your UI logic:
UX patterns for offline state
Showing a sync status indicator
Display a small indicator in your UI that reflects the current connectivity. Users should know whether their changes have synced.- React
- Pattern guidance
Pending changes indicator
You can query the local event log to count events that have not yet been confirmed by the sync backend and surface that count in your UI.Disabling network-dependent features
Some features — for example, sharing a document URL that others can access — require the sync backend to be reachable. Use the connectivity status to disable or hide these features gracefully rather than showing an error after the fact.Testing offline behavior
Use the DevTools sync latch
The LiveStore DevTools include a sync latch that closes the sync connection without affecting the rest of the application. Toggle it to simulate going offline and verify your UI responds correctly.
Test pending event persistence
Commit several events while offline (latch closed), reload the page, then re-enable the latch. Confirm all events sync correctly and state is consistent.
Test concurrent edits
Open two browser tabs with different simulated offline states. Make conflicting edits in each tab, then bring both online. Verify the final state is correct and consistent.