DevTools API
DevTools has two halves. The bridge lives in @quantajs/core and collects
the data; the UI lives in @quantajs/devtools and renders it. You need
both, and the bridge is off until you turn it on.
import { enableDevTools, disableDevTools, devtools } from '@quantajs/core';
import { mountDevTools, DevTools } from '@quantajs/devtools';
enableDevTools(options?)
Attaches the bridge and starts collecting. Until this is called, nothing is
collected and nothing is attached to window.
function enableDevTools(options?: DevToolsOptions): void;
interface DevToolsOptions {
/** Property paths to redact from emitted events, e.g. ['token', 'user.ssn']. */
redact?: string[];
}
Redaction applies to state values and to action arguments that are objects
carrying a matching key. Matches become [redacted].
if (process.env.NODE_ENV === 'development') {
enableDevTools({ redact: ['token', 'user.ssn'] });
}
Note:
This is a security boundary. DevTools observes full store contents and every
argument to every action, which routinely includes credentials and personal
data. Before 2.1 the bridge enabled itself whenever process.env.NODE_ENV was
not statically replaced — true for CDN bundles, Deno and plain
<script type="module"> — leaving it on in production. Guard the call and keep
it out of production builds.
Enable it before creating stores. It registers stores created after it is enabled.
disableDevTools()
function disableDevTools(): void;
Detaches the bridge and stops collecting.
devtools
The bridge object itself, for building a custom DevTools UI. devtools.enabled
reports whether collection is on. Most applications never touch this.
@quantajs/devtools exports
mountDevTools(options?)DevTools(Preact component)
mountDevTools(options?)
Mounts Quanta DevTools and returns a cleanup function.
Signature
function mountDevTools(options?: DevToolsOptions): () => void;
Mount options
interface DevToolsOptions {
visible?: boolean;
target?: HTMLElement | string;
onError?: (error: Error) => void;
}
Note:
This is a different type from core's DevToolsOptions above, despite the
shared name. visible controls whether the panel renders; it has no effect on
whether data is collected. That is enableDevTools().
Option Details
visibleundefined(default): auto-detect development modetrue: force visiblefalse: no-op mount
target- default is
'body' - supports CSS selector string or
HTMLElement
- default is
onError- optional callback for non-fatal mount issues (for example, missing target)
Return Value
Returns cleanup() => void to unmount and release listeners/timers.
Examples
Basic
Both halves:
import { enableDevTools } from '@quantajs/core';
import { mountDevTools } from '@quantajs/devtools';
enableDevTools();
mountDevTools();
Mounting the UI without enabling the bridge produces an empty panel.
Custom Target
mountDevTools({ target: '#devtools-root' });
Error Hook
mountDevTools({
target: '#missing-root',
onError(error) {
console.warn(error.message);
},
});
Dynamic Import (Production-Safe)
if (import.meta.env.DEV) {
enableDevTools();
import('@quantajs/devtools').then(({ mountDevTools }) => {
mountDevTools();
});
}
DevTools Component
Low-level Preact component for manual composition.
import { render } from 'preact';
import { DevTools } from '@quantajs/devtools';
render(<DevTools />, document.body);
For React apps, prefer QuantaDevTools from @quantajs/react/devtools.
Bridge Events (for context)
Once enabled, the bridge emits:
STORE_INITSTATE_CHANGEACTION_CALL
The UI subscribes to these; you do not wire it up yourself. A listener that throws is contained and can no longer break application state writes, which it could in 2.0.0.