Skip to content
Back to skills

Xstate Typegen

ASecurity

> Generate full type safety for XState machines with typegen (v4) and the setup pattern (v5)

  • 20 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 11, 2026
toolstypescriptgoapi

Works with

  • cli
  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned September 11, 2026

npx -y skills add Intense-Visions/harness-engineering --skill xstate-typegen --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Xstate Typegen?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Xstate Typegen
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/intense-visions-xstate-typegen/badge)](https://www.skillsdirectory.com/skills/intense-visions-xstate-typegen)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# XState Typegen

> Generate full type safety for XState machines with typegen (v4) and the setup pattern (v5)

## When to Use

- Getting TypeScript errors about missing event types in guards or actions
- Wanting autocompletion for state names, event types, and action names
- Ensuring type safety between machine definition and service implementations
- Setting up a new XState project with strict typing from the start

## Instructions

### XState v5 (recommended): setup pattern

1. Use `setup()` to declare all types, actions, guards, actors, and delays before creating the machine.
2. Define `types` with TypeScript `as` assertion for context, events, input, and output.
3. All actions, guards, and actors referenced in the machine must be declared in `setup()` — runtime errors if missing.
4. The machine is fully typed from the `setup()` declaration — no separate code generation step.

```typescript
// auth.machine.ts (v5)
import { setup, assign, fromPromise } from 'xstate';

interface AuthContext {
  user: { id: string; name: string } | null;
  error: string | null;
}

type AuthEvent = { type: 'LOGIN'; email: string; password: string } | { type: 'LOGOUT' };

const authMachine = setup({
  types: {} as {
    context: AuthContext;
    events: AuthEvent;
    input: { redirectUrl?: string };
  },
  actors: {
    authenticate: fromPromise(async ({ input }: { input: { email: string; password: string } }) => {
      const res = await fetch('/api/login', {
        method: 'POST',
        body: JSON.stringify(input),
      });
      if (!res.ok) throw new Error('Auth failed');
      return res.json() as Promise<{ id: string; name: string }>;
    }),
  },
  actions: {
    setUser: assign({
      user: (_, params: { id: string; name: string }) => params,
    }),
    clearUser: assign({ user: null, error: null }),
    setError: assign({
      error: (_, params: { message: string }) => params.message,
    }),
  },
  guards: {
    isAuthenticated: ({ context }) => context.user !== null,
  },
}).createMachine({
  id: 'auth',
  initial: 'idle',
  context: ({ input }) => ({
    user: null,
    error: null,
  }),
  states: {
    idle: {
      on: { LOGIN: 'authenticating' },
    },
    authenticating: {
      invoke: {
        src: 'authenticate',
        input: ({ event }) => ({
          email: (event as { email: string }).email,
          password: (event as { password: string }).password,
        }),
        onDone: {
          target: 'authenticated',
          actions: { type: 'setUser', params: ({ event }) => event.output },
        },
        onError: {
          target: 'error',
          actions: {
            type: 'setError',
            params: ({ event }) => ({ message: (event.error as Error).message }),
          },
        },
      },
    },
    authenticated: {
      on: { LOGOUT: { target: 'idle', actions: 'clearUser' } },
    },
    error: {
      on: { LOGIN: 'authenticating' },
    },
  },
});
```

### XState v4: typegen

1. Install `@xstate/cli`: `npm install -D @xstate/cli`.
2. Add `tsTypes: {}` to the machine config to enable typegen.
3. Run `xstate typegen "src/**/*.machine.ts"` to generate `.typegen.ts` files.
4. The generated file provides exact types for which events are valid in which states, which services are invoked, and which actions/guards are used.

```typescript
// v4 with typegen
import { createMachine } from 'xstate';

const machine = createMachine({
  tsTypes: {} as import('./auth.machine.typegen').Typegen0,
  schema: {
    context: {} as AuthContext,
    events: {} as AuthEvent,
    services: {} as { authenticate: { data: User } },
  },
  // ...
});
```

## Details

**v5 setup benefits over v4 typegen:**

- No code generation step — types flow from `setup()` directly
- Actions and guards must exist at declaration time — catches typos immediately
- Actor input/output types are inferred from `fromPromise`, `fromCallback`, etc.
- No `.typegen.ts` files to maintain or commit

**Typing event narrowing in actions:** In v5, action implementations receive the full event union. Narrow when needed:

```typescript
actions: {
  handleLogin: ({ event }) => {
    if (event.type === 'LOGIN') {
      console.log(event.email); // Typed correctly
    }
  },
},
```

**Common type issues:**

- `Type 'string' is not assignable to type 'never'` in transitions — usually means the event is not listed in the events type
- Missing action/guard in `setup()` — v5 requires all referenced names to be declared upfront
- Circular type inference — break cycles by explicitly typing `context` function return

## Source

https://stately.ai/docs/typescript

## Process

1. Read the instructions and examples in this document.
2. Apply the patterns to your implementation, adapting to your specific context.
3. Verify your implementation against the details and edge cases listed above.

## Harness Integration

- **Type:** knowledge — this skill is a reference document, not a procedural workflow.
- **No tools or state** — consumed as context by other skills and agents.

## Success Criteria

- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.

Files in this skill

  • SKILL.md5.1 KB
  • skill.yaml722 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…