TypeScript icon, indicating that this package has built-in type declarations

0.8.0 • Public • Published


This package contains inspection tools for XState.


Inspector running from CodeSandbox

Check out the XState + Vue Minute Timer + Viz example on CodeSandbox


  1. Install with npm or yarn:
npm install @xstate/inspect
# or yarn add @xstate/inspect


<script src="https://unpkg.com/@xstate/inspect/dist/xstate-inspect.umd.min.js"></script>

By using the global variable XStateInspect

  1. Import it at the beginning of your project, before any other code is called:
import { inspect } from '@xstate/inspect';

  // options
  // url: 'https://stately.ai/viz?inspect', // (default)
  iframe: false // open in new window
  1. Add { devTools: true } to any interpreted machines you want to visualize:
import { interpret } from 'xstate';
import { inspect } from '@xstate/inspect';
// ...

const service = interpret(someMachine, { devTools: true });


  • url (optional) - The endpoint that the Inspector sends events to. Default: https://stately.ai/viz?inspect
  • iframe (optional) - The iframe that loads the provided URL. If iframe is set to false, then a new tab is opened instead.
  • devTools (optional) - Allows custom implementation for lifecycle hooks.
  • serialize (optional) - A custom serializer for messages sent to the URL endpoint. Useful for sanitizing sensitive information, such as credentials, from leaving your application.
  • targetWindow (optional) - Provide a pre-existing window location that will be used instead of opening a new window etc. When using this option, you must still provide the url value due to security checks in browser APIs, and the iframe option is ignored in such a case.


Add a custom serializer to @xstate/inspector events and transitions messages

When is this useful?

  • Remove sensitive items, such as credentials
  • Add additional custom handling
// Remove credentials from being forwarded
  serialize: (key: string, value: any) => {
    return key === "credentials" && typeof value === "object" ? {} : value;

// Add a custom local log
  serialize: (key: string, value: any) => {
    if (key === "ready") {
      console.log("Detected ready key");
    return value;

Easily log all machine events and transitions

When is this useful?

  • Allows you to quickly see all events and transitions for your machines
  • No need to add manual console.log statements to your machine definitions
// The URL and port of your local project (ex. Vite, Webpack, etc).
const url = ""

const inspector = inspect({
  iframe: undefined,
  targetWindow: window

// In the same window, subsribe to messages from @xstate/inspector

// Start your machine, and all events generated are logged to the console
interpret(machine, { devTools: true }).start({});

Send events to a separate, locally hosted tool

When is this useful?

  • Forward messages to a custom endpoint, that you can then listen to and add custom handling for messages
// In your client application
const url = ""
const targetWindow = window.open(url);

const inspector = inspect({
  // The URL must still be provided. This is used by postMessage, as it's
  // not possible to do targetWindow.location for security reasons

// In the second, hosted application
createWindowReceiver({}).subscribe((event) => {
  if (event.type === "service.register") {
    // Do something when a new machine is started

  } else if (event.type === "service.stop") {
    // Do something when a machine enters a terminal state

  } else if (event.type === "service.event") {
    // Do something when a machine recieves an event

  } else if (event.type === "service.state") {
    // Do something when a machine enters to a new state
    // Note: Does not handle transitional states.

Package Sidebar


npm i @xstate/inspect

Weekly Downloads






Unpacked Size

72.3 kB

Total Files


Last publish


  • xstate-release-bot
  • andarist
  • davidkpiano