SkillAgentSearch skills...

Jssm

Fast, easy Javascript finite state machines with visualizations; enjoy a one liner FSM instead of pages. MIT; Typescripted; 100% test coverage. Implements the FSL language.

Install / Use

/learn @StoneCypher/Jssm

README

<!-- I8, 8 ,8I 88 `8b d8b d8' "" "8, ,8"8, ,8" Y8 8P Y8 8P ,adPPYYba, 8b,dPPYba, 8b,dPPYba, 88 8b,dPPYba, ,adPPYb,d8 `8b d8' `8b d8' "" `Y8 88P' "Y8 88P' `"8a 88 88P' `"8a a8" `Y88 `8a a8' `8a a8' ,adPPPPP88 88 88 88 88 88 88 8b 88 `8a8' `8a8' 88, ,88 88 88 88 88 88 88 "8a, ,d88 `8' `8' `"8bbdP"Y8 88 88 88 88 88 88 `"YbbdP"Y8 aa, ,88 "Y8bbdP" This file is generated. If you edit it, the edits ***will be lost***. ---------------------- Please edit the file it's derived from, instead: `./src/md/readme_base.md` * Generated for version 5.105.0 at 1/8/2026, 5:15:34 PM -->

jssm 5.105.0

Easy. Small. Fast. TS, es6, es5. Node, Browser. 100% coverage. Property tests. Fuzz tests. Language tests for a dozen languages and emoji. Easy to share online. Easy to embed.

Readable, useful state machines as one-liner strings.

5,084 tests, run 5,975 times.

  • 5,075 specs with 99.9% coverage.
  • 9 fuzz tests with 12.3% coverage.

With 3,028 lines, that's about 1.7 tests per line, or 2.0 generated tests per line.

Meet your new state machine library.

<a href="https://stonecypher.github.io/jssm-viz-demo/graph_explorer.html" target="_blank" rel="noopener noreferrer">TRY THE LIVE EDITOR</a>

<a href="https://discord.gg/9P95USqnMK">Discord community</a> - <a href="https://stonecypher.github.io/jssm/docs/">Documentation</a> - <a href="https://github.com/StoneCypher/fsl/issues">Issue tracker</a> - <a href="https://github.com/StoneCypher/jssm/actions">CI build history</a>

<a href="https://discord.gg/9P95USqnMK">Discord community</a>

<br/><br/>

Wouldn't it be nice if your TypeScript and Javascript state machines were simple and readable one-liners?

import { sm } from 'jssm';

const TrafficLight = sm`Red -> Green -> Yellow -> Red;`;
<br/>

Wouldn't it be great if they were easy to work with?

const log = s => console.log(s);

log( TrafficLight.state() );  // 'Red'

Machine.transition('Green');  // true
log( TrafficLight.state() );  // 'Green'
<br/>

What if the notation supported action names easily?

const TLWA = sm`Red 'next' -> Green 'next' -> Yellow 'next' -> Red;`;  // TLWA = Traffic Light With Actions

log( TLWA.state() );  // 'Red'

TLWA.action('next');  // true
log( TLWA.state() );  // 'Green'

TLWA.action('next');  // true
log( TLWA.state() );  // 'Yellow'

TLWA.action('next');  // true
log( TLWA.state() );  // 'Red'
<br/>

What if integration with the outside was straightforward?

const MTL = sm`Red 'next' -> Green 'next' -> Yellow 'next' -> Red;`  // MTL = More Traffic Lights
              .hook('Red', 'Green', () => log('GO GO GO') )          // node will jump the gun when you hit return, though
              .hook_entry('Red', () => log('STOP') );                // so put it on one line in node

log( MTL.state() );  // 'Red'

MTL.action('next');  // true, console logs 'GO GO GO'
log( MTL.state() );  // 'Green'

MTL.action('next');  // true
log( MTL.state() );  // 'Yellow'

MTL.action('next');  // true, console logs 'STOP'
log( MTL.state() );  // 'Red'
<br/>

What if the machine followed JS standards, and distinguished refusals as false from mistakes as thrown?

const ATL = sm`Red -> Green -> Yellow -> Red;`;  // ATL = Another Traffic Light

log( ATL.state() );         // 'Red' - uses 1st state unless told otherwise
ATL.transition('Yellow');   // false (Yellow isn't allowed from Red)
ATL.transition('Blue');     // throws (Blue isn't a state at all)
<br/>

What if there were easy convenience notations for lists, and for designating main-path => vs available path -> vs only-when-forced ~> ?

const TrafficLightWithOff = sm`
  Red => Green => Yellow => Red;
  [Red Yellow Green] ~> Off -> Red;
`;
<br/>

What if that were easy to render visually?

const TrafficLightWithOff = sm`
  Red => Green => Yellow => Red;
  [Red Yellow Green] ~> Off -> Red;
`;
<br/> <img src="https://raw.githubusercontent.com/StoneCypher/jssm/master/src/assets/doc%20light%20unstyled.png"/> <br/>

What if that were easy to render visually, with styling, in PNG, JPEG, or SVG?

const TrafficLightWithOff = sm`
  Red => Green => Yellow => Red;
  [Red Yellow Green] ~> Off -> Red;

  flow: left;

  state Red    : { background-color: pink;        corners: rounded; };
  state Yellow : { background-color: lightyellow; corners: rounded; };
  state Green  : { background-color: lightgreen;  corners: rounded; };

  state Off : {
    background-color : steelblue;
    text-color       : white;
    shape            : octagon;
    linestyle        : dashed;
  };
`;
<br/> <img src="https://raw.githubusercontent.com/StoneCypher/jssm/master/src/assets/doc%20light%20styled.png"/> <br/>

What if the machine was lighting fast, able to do tens of millions of transitions per second?

<img src="https://raw.githubusercontent.com/StoneCypher/jssm/master/src/assets/speed%20claim.png"/> <br/>
  • What if the machine and language had extensive 100% test coverage with thousands of cases?
  • What if the machine gave extensive Typescript introspection support?
  • What if the machine had been around and active since May 2017?
  • What if the machine was MIT licensed, end to end?

But, above all else:

What if it was easy?

<br/><br/>

Introducing JSSM

Meet JSSM: the <b><u>J</u></b>ava<b><u>s</u></b>cript <b><u>S</u></b>tate <b><u>M</u></b>achine.

State machines can make your code cleaner, safer, and more trustworthy.

And, with the right language, state machines can be easy and fun.

<a href="https://stonecypher.github.io/jssm-viz-demo/graph_explorer.html" target="_blank" rel="noopener noreferrer">TRY THE LIVE EDITOR</a>

<br/>

What is JSSM?

JSSM is a Javascript state machine implementing Finite State Language, with a terse DSL and a simple API. 100% test coverage; typed with Flowtype. MIT licensed.

The NPM package includes pure es6, a cjs es5 bundle, and .d.ts typings. The repository includes the original typescript, the bundle, the es6, documentation, tests, tutorials, and so on.

Try it live!

Visualize with jssm-viz, or at the command line with jssm-viz-cli.

Language test cases for Belorussian, English, German, Hebrew, Italian, Russian, Spanish, Ukrainian, and Emoji. Please help to make sure that your language is well handled!

<div id="badge_style_hook">

Actions Status

GitHub forks GitHub watchers GitHub stars GitHub followers

License Open issues Closed issues Travis status Coveralls status

NPM version CDNjs version NPM downloads

<img src="https://starchart.cc/StoneCypher/jssm.svg" width="50%"> </div>

<br/><br/>

TL;DR

Specify finite state machines with a brief syntax. Run them; they're fast. Make mistakes; they're strict. Derive charts. Save and load states, and histories. Make machine factories to churn out dozens or thousands of instances. Impress friends and loved ones. Cure corns and callouses.

Red 'Proceed' -> Green 'Proceed' -> Yellow 'Proceed' -> Red;

This will produce the following FSM (graphed with jssm-viz):

You'll build an executable state machine.

<br/><br/>

Why

As usual, a valid question.

<br/>

Why state machines

State machines are a method of making your software better able to prevent illegal states. Similar to type systems, SQL constraints, and linters, state machines are a way to teach the software to catch mistakes in ways you define, to help lead to better software.

The major mechanism of a state machine is to define states, the transitions between them, a

View on GitHub
GitHub Stars369
CategoryDevelopment
Updated7d ago
Forks24

Languages

JavaScript

Security Score

100/100

Audited on Mar 19, 2026

No findings