Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

eslint-plugin-machina

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-machina

ESLint plugin for static analysis of machina FSM configs.

latest
Source
npmnpm
Version
0.1.3
Version published
Weekly downloads
12
20%
Maintainers
1
Weekly downloads
 
Created
Source

eslint-plugin-machina

ESLint plugin for static analysis of machina FSM configs. Catches structural issues at lint time — unreachable states, infinite _onEnter loops, missing handlers — without running the machine.

Built on machina-inspect. ESLint 9 flat config only.

Install

npm install --save-dev eslint-plugin-machina
# or
pnpm add -D eslint-plugin-machina

machina-inspect is pulled in automatically as a dependency. For TypeScript files, you also need @typescript-eslint/parser:

npm install --save-dev @typescript-eslint/parser

Setup

// eslint.config.mjs
import machina from "eslint-plugin-machina";

export default [
    machina.configs.recommended,
    // ... your other configs
];

With TypeScript

// eslint.config.mjs
import tsParser from "@typescript-eslint/parser";
import machina from "eslint-plugin-machina";

export default [
    {
        files: ["src/**/*.ts"],
        languageOptions: { parser: tsParser },
    },
    machina.configs.recommended,
];

Manual configuration

// eslint.config.mjs
import machina from "eslint-plugin-machina";

export default [
    {
        plugins: { machina },
        rules: {
            "machina/unreachable-state": "warn",
            "machina/onenter-loop": "error",
            "machina/missing-handler": "off",
        },
    },
];

Rules

RuleDefaultTypeDescription
machina/unreachable-state"warn"problemStates with no inbound path from initialState
machina/onenter-loop"error"problemUnconditional _onEnter transition cycles
machina/missing-handler"off"suggestionStates missing handlers for inputs other states handle

machina/unreachable-state

Detects states with no inbound path from initialState. Unreachable states are dead code.

// Triggers warning on "broken"
createFsm({
    id: "traffic-light",
    initialState: "green",
    states: {
        green: { timeout: "yellow" },
        yellow: { timeout: "red" },
        red: { timeout: "green" },
        broken: {}, // no transitions lead here
    },
});

machina/onenter-loop

Detects unconditional _onEnter transition cycles that will infinite-loop the runtime. Only flags cycles where every edge is unconditional — conditional bounces like if (ctx.error) return "failed" are intentional patterns, not bugs.

// Triggers error — unconditional cycle: a -> b -> a
createFsm({
    id: "bouncy",
    initialState: "a",
    states: {
        a: { _onEnter: () => "b" },
        b: { _onEnter: () => "a" },
    },
});

machina/missing-handler

Detects states that don't handle inputs handled by other states in the same FSM. Off by default — many FSMs have asymmetric handlers by design (terminal states, initialization states, etc.). States with a * catch-all handler are excluded.

// Triggers suggestion — "idle" doesn't handle "stop" or "pause"
createFsm({
    id: "player",
    initialState: "idle",
    states: {
        idle: { start: "running" },
        running: { stop: "idle", pause: "paused" },
        paused: { resume: "running", stop: "idle" },
    },
});

How it works

The plugin listens for createFsm() and createBehavioralFsm() call expressions, builds a StateGraph from the AST using machina-inspect's graph IR, then runs the same structural checks machina-inspect provides. Findings are reported as ESLint diagnostics at the call site.

_child resolution

Child FSM references on _child are resolved when they're:

  • Inline calls: _child: createFsm({ ... }) directly in the state config
  • const references: _child: myChildFsm where myChildFsm is a const declaration bound to a createFsm() / createBehavioralFsm() call in the same module

Cross-module imports and let/var bindings are silently skipped — no false positives, just no analysis for those cases.

See also

  • machina-inspect — programmatic API for the same structural checks
  • machina-test — Jest/Vitest custom matchers for graph-level assertions in your test suite
  • machina-explorer — browser-based paste-and-analyze UI

License

MIT

FAQs

Package last updated on 06 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts