DevTools are available to LiveStore sponsors. See the LiveStore GitHub repository for details.
DevTools overview
The DevTools panel includes the following features:Data browser
Browse and edit your SQLite tables in real time with two-way sync. Changes made in the browser reflect in the app immediately.
Eventlog browser
See every event committed to the store in chronological order. Filter, search, and inspect individual event payloads.
Query inspector
View all active queries, their current results, and which signals they depend on.
Sync status
Monitor the connection to the sync backend. Toggle the sync latch to simulate offline behavior.
Signals graph
Visualize the dependency graph of computed signals and observe which queries trigger re-renders.
SQLite playground
Run arbitrary SQL queries against the live SQLite database directly from the DevTools panel.
Installing DevTools
Web (Vite)
Install the@livestore/devtools-vite package and add the plugin to your Vite config:
Chrome extension
You can also use the DevTools Chrome extension instead of the Vite-served panel.Download the extension
Download the
.zip matching your LiveStore version from the GitHub releases page. For example: livestore-devtools-chrome-0.3.0.zip.Enable Developer mode
Navigate to
chrome://extensions/ and enable Developer mode using the toggle in the top-right corner.Expo (React Native)
Install the@livestore/devtools-expo package and configure your Metro bundler:
Node.js adapter
DevTools are configured automatically formakePersistedAdapter. The DevTools URL is logged when the app starts.
DevTools are not currently supported for
makeInMemoryAdapter in the Node.js adapter.Using the eventlog browser
The eventlog browser is the most useful tool for debugging unexpected state. What it shows:- Every event committed to the store, in order
- Event name, timestamp, client ID, and full payload
- Which materializer ran for each event
- Reproduce the bug or unexpected state in your app
- Open the eventlog browser
- Identify the event (or missing event) that caused the incorrect state
- Inspect the payload to confirm it contains the values you expected
Using the query inspector
The query inspector shows all currently activequeryDb subscriptions and their live results.
What it shows:
- The SQL query string for each subscription
- Current result set
- Which signals the query depends on
- Last time the query re-ran
- If a component is not updating when you expect it to, check the query inspector to confirm the query is active and returning the expected rows
- If a component is re-rendering too often, inspect the query’s signal dependencies to find unnecessary invalidations
Using the signals/reactivity graph
The signals graph visualizes computed signals and their dependency chains. Each node represents a signal or query; edges represent dependencies. Use the signals graph to:- Find computations that have unexpectedly large dependency sets
- Trace why a specific computation re-ran after a commit
- Identify signals that are recomputed more often than necessary
Debugging helpers on the store
Thestore object exposes a _dev property with helpers for programmatic debugging:
The
_dev API is intended for development and debugging use only. Do not rely on it in production code — it may change between versions.exposeDebugUtils()
In development, you can expose the store and debug utilities on the global window object to inspect them from the browser console:
OpenTelemetry integration
LiveStore supports OpenTelemetry tracing via theotelOptions configuration. Traces capture store operations, event commits, materializer runs, and sync activity, giving you a detailed performance and correctness timeline.
Traces are exported to any OTLP-compatible backend (Jaeger, Honeycomb, Grafana Tempo, and so on). Set the
VITE_OTEL_EXPORTER_OTLP_ENDPOINT environment variable to your collector URL.
Debugging sync issues
Events are not syncing to other clients
Events are not syncing to other clients
- Open the Sync status panel in DevTools and verify the connection is active.
- Check the Eventlog browser — confirm the events appear locally with the expected payloads.
- Check your sync backend logs for
validatePayloaderrors or connection rejections. - Verify your
syncPayloadauth token is valid and has not expired.
State is inconsistent between clients
State is inconsistent between clients
Because LiveStore state is deterministic from the event log, inconsistent state between clients means the event logs are diverging. Check:
- Whether all clients are connected to the same store ID
- Whether an
unknownEventHandlingstrategy is silently dropping events on older clients - Whether any materializer has non-deterministic behavior (random values, timestamps, side effects)
Slow or missing re-renders
Slow or missing re-renders
- Open the Query inspector and verify your query is active and returning updated rows
- Check the Signals graph for unexpected dependency chains that may be missing or over-broad
- Confirm you are using
useQuery(or the equivalent for your framework) rather than reading state imperatively
Testing offline sync behavior
Testing offline sync behavior
Use the sync latch in the Sync status panel to close the sync connection without affecting the rest of the application. Commit events while offline, then re-enable the latch and verify events sync correctly.
Recommended debugging workflow
- Reproduce the issue
- Open the Eventlog browser — check that the expected events were committed with correct payloads
- Open the Data browser — check the current state of the relevant SQLite tables
- If state is wrong given correct events, check the materializer for that event type
- If events are missing, check the application code that calls
store.commit() - If sync is wrong, check the Sync status panel and your backend logs