Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/statelyai/xstate/llms.txt

Use this file to discover all available pages before exploring further.

Spawns a child actor from actor logic.
import { spawnChild } from 'xstate';

Signature

function spawnChild<
  TContext extends MachineContext,
  TExpressionEvent extends EventObject,
  TParams extends ParameterizedObject['params'] | undefined,
  TEvent extends EventObject,
  TActor extends ProvidedActor
>(
  src: TActor['src'] | AnyActorLogic,
  options?: SpawnActionOptions<TContext, TExpressionEvent, TEvent, TActor>
): ActionFunction

Parameters

src
string | AnyActorLogic
required
The actor logic to spawn. Can be:
  • String: reference to an actor defined in the machine’s actors implementation
  • Actor logic: inline actor logic (machine, promise, observable, etc.)
options
SpawnActionOptions
Optional configuration object:

Returns

ActionFunction
ActionFunction
An action function that spawns the child actor when executed.

Examples

Spawn from actor implementation

import { createMachine, spawnChild, setup } from 'xstate';

const childMachine = createMachine({
  initial: 'active',
  states: {
    active: {}
  }
});

const parentMachine = setup({
  actors: {
    child: childMachine
  }
}).createMachine({
  on: {
    SPAWN: {
      actions: spawnChild('child', { id: 'myChild' })
    }
  }
});

Spawn with input

const machine = setup({
  types: {} as {
    context: { count: number };
  },
  actors: {
    counter: createMachine({
      types: {} as {
        input: { initialCount: number };
      },
      context: ({ input }) => ({
        count: input.initialCount
      })
    })
  }
}).createMachine({
  context: { count: 0 },
  on: {
    SPAWN_COUNTER: {
      actions: spawnChild('counter', {
        id: 'counter',
        input: ({ context }) => ({
          initialCount: context.count
        })
      })
    }
  }
});

Spawn inline actor

import { fromPromise } from 'xstate';

const machine = createMachine({
  on: {
    FETCH: {
      actions: spawnChild(
        fromPromise(async () => {
          const response = await fetch('/api/data');
          return response.json();
        }),
        {
          id: 'fetchData'
        }
      )
    }
  }
});

Dynamic actor ID

const machine = setup({
  actors: {
    worker: createMachine({})
  }
}).createMachine({
  types: {} as {
    events: { type: 'SPAWN_WORKER'; workerId: string };
  },
  on: {
    SPAWN_WORKER: {
      actions: spawnChild('worker', {
        id: ({ event }) => `worker-${event.workerId}`
      })
    }
  }
});

Spawn with sync snapshot

const machine = createMachine({
  types: {} as {
    context: { childState: string };
  },
  context: { childState: 'unknown' },
  on: {
    SPAWN: {
      actions: [
        spawnChild(childMachine, {
          id: 'child',
          syncSnapshot: true
        }),
        assign({
          childState: ({ context }) => {
            const child = context.children?.child;
            return child?.getSnapshot().value ?? 'unknown';
          }
        })
      ]
    }
  }
});

Multiple spawned children

import { enqueueActions } from 'xstate';

const machine = setup({
  actors: {
    task: createMachine({
      types: {} as {
        input: { taskId: string };
      }
    })
  }
}).createMachine({
  types: {} as {
    context: { taskIds: string[] };
  },
  context: { taskIds: ['task1', 'task2', 'task3'] },
  on: {
    SPAWN_ALL: {
      actions: enqueueActions(({ enqueue, context }) => {
        context.taskIds.forEach((taskId) => {
          enqueue.spawnChild('task', {
            id: taskId,
            input: { taskId }
          });
        });
      })
    }
  }
});

Notes

Spawned actors are automatically started after being spawned. They will continue running until they reach a final state or are explicitly stopped.
Store spawned actor references in context if you need to interact with them later using sendTo or stopChild.
If an actor with the specified src is not found in the machine’s implementations, a warning will be logged in development mode.

Build docs developers (and LLMs) love