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

  • visible
    • undefined (default): auto-detect development mode
    • true: force visible
    • false: no-op mount
  • target
    • default is 'body'
    • supports CSS selector string or HTMLElement
  • 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_INIT
  • STATE_CHANGE
  • ACTION_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.

Learn More