Statelight

Watch your state machine light up, live.

Drop one script tag next to any hand-rolled JS state machine and a floating panel shows its current state, lighting up the transition path live as you interact. No framework, no build step, nothing to import into your own code.

<script type="module">
  import { attach } from
    'https://cdn.jsdelivr.net/npm/statelight/dist/statelight.js';

  const machine = { state: 'idle' };

  attach(machine, {
    transitions: {
      idle: { start: 'running' },
      running: { stop: 'idle' }
    }
  });

  // Anywhere in your own code, unmodified:
  machine.state = 'running';
</script>

This demo needs JavaScript enabled. Statelight attaches to a real state machine live on this page.

red

How it works

  1. 1

    Add one script tag

    No bundler, no npm install required to try it. Import straight from a CDN.

  2. 2

    Call attach(machine)

    attach(machine, { transitions });
  3. 3

    Watch it light up

    Every assignment to machine.state updates the panel and pulses the live edge instantly, with no polling.

What you get

  • Live transition graph with the active edge lit up as your machine moves through it.
  • Collapsible, draggable panel that remembers where you left it, per page.
  • Watch more than one machine on the same page: panels cascade instead of overlapping.
  • No dependencies, no build step, no framework lock-in. Works with any plain object.

Questions

What is Statelight?
A small debugger for hand-rolled JavaScript state machines. It attaches to a plain object that has a state property, shows the current state in a floating panel, and, when you hand it a transition map, draws the state graph and lights up each edge as your machine moves through it.
Do I need XState or a state machine library?
No. Statelight is built for the machines you already wrote by hand: a state field and some if or switch logic. There is nothing to migrate to and no pattern to adopt. If you do use a library, Statelight still works as long as the state lives on a readable, writable property.
How does it watch state without changing my code?
It replaces the watched property with a transparent getter/setter. Reads and writes behave exactly as before, so machine.state = 'running' keeps working unchanged while every transition is recorded and rendered. Call detach() to restore the plain property.
Does it work with React, Vue, or Svelte?
It is framework-agnostic. Statelight only cares about a plain object with a mutable state property, so it runs next to any framework or none at all. It is meant for debugging your own logic, not for driving a component tree.
How big is it, and what does it depend on?
Zero runtime dependencies, and the shipped bundle targets under 3kb gzipped. You can drop it in from a CDN with one script tag, or install it from npm and bundle it yourself.