Use XState to decide what an interface is doing, and Svelte to animate the resulting DOM changes. The @xstate/svelte integration connects an actor to a Svelte component; Svelte’s transition: directive handles entry and exit, while animate: handles reordering existing keyed-list items. When application behavior must wait for an animation, send an explicit machine event from a Svelte transition lifecycle handler rather than treating a state change as proof that the animation has finished.
How XState and Svelte fit together
XState models behavioral states and the events that move an interface between them. Svelte renders the current state and interpolates visual changes. Keeping those responsibilities distinct means the machine can express meaningful phases and rules without tracking every animation frame.
Stately’s @xstate/svelte documentation describes the package as utilities for using XState with Svelte. Its useMachine(machine, options?) API creates an actor and starts it for the lifetime of the component. It returns snapshot, a Svelte store for the current machine state; send, which sends events to the actor; and actorRef, the actor reference. The page currently labels its documentation XState v6 alpha, so check the installed package versions and their matching API documentation before adopting an example in a project.
For hierarchical or parallel machines, use state.matches(...) to check a state: the state value is an object rather than necessarily a simple string. Keep the machine event-driven—for example, send an event when a user requests that a panel open—and derive the rendered block or classes from the current snapshot.
#1 Best Overall
Choose the Svelte directive for the DOM change
| Visual change | Svelte primitive | What it does |
|---|---|---|
| An element enters or leaves the DOM | transition: |
Runs an intro or outro as a state change creates or destroys the element’s block; a bidirectional transition can reverse while in progress. |
| An existing keyed-list item changes position | animate: |
Animates an item’s position when its index changes in an immediate child of a keyed each block. It does not animate an item merely being added or removed. |
| A decorative change with no behavioral significance | Usually a local Svelte transition or style | Keep the effect local rather than adding machine states for visual details that do not affect application behavior. |
These APIs address different DOM changes; a list reorder is not the same event as an element entering or leaving. See Svelte’s references for the transition directive and animate directive.
Scope transitions deliberately
Svelte transitions are local by default: they run when their own block is created or destroyed. Add the |global modifier when the transition should also run because an enclosing block is being created or destroyed. This distinction matters when nested conditional blocks make the visible element’s own block persist even as an ancestor changes.
Rank #2
Model meaningful phases, not animation frames
If opening and closing have behavioral consequences, represent phases such as closed, opening, open, and closing in the machine. These names are a practical design pattern, not a canonical architecture prescribed by XState or Svelte. Use machine events for user intent and external outcomes; have the Svelte component derive its conditional blocks, classes, and transition parameters from the actor snapshot.
Keep purely decorative interpolation in Svelte. Modeling every intermediate visual frame as a machine state adds behavioral complexity without helping unless the application has a concrete reason to react to those frames.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Wait for an intro or outro when behavior depends on completion
A machine entering a state does not, by itself, establish that the corresponding Svelte animation has finished. Svelte exposes transition lifecycle events—introstart, introend, outrostart, and outroend—so a component can send a deliberate event to the actor when the relevant visual phase completes.
- Send the machine an intent event, such as a request to close a panel.
- Let the machine enter the behaviorally meaningful closing phase and let Svelte begin the outro for the affected block.
- If later behavior must wait, handle the outro completion event and send an explicit completion event to the actor.
- Define what should happen if the transition is interrupted or reversed; Svelte’s bidirectional transitions can reverse while in progress, so a completion event should not be assumed to describe an uninterrupted path.
Svelte keeps elements in an outroing block in the DOM until all transitions within that block finish. That makes the lifecycle completion signal useful when removal timing matters, but the application should still decide how to handle competing events and reversals.
Rank #4
Account for reduced motion and custom effects
Svelte documents that its transitions are driven by the Web Animations API. Consequently, a global CSS prefers-reduced-motion rule that sets CSS transition and animation durations to zero does not, on its own, disable Svelte transitions. Use Svelte’s prefersReducedMotion facility to adjust or disable them for users who request reduced motion. See the Svelte transition reference for the documented transition and motion APIs.
Custom transition functions can provide timing and easing information along with CSS keyframes or a tick callback. Svelte recommends CSS where possible because Web Animations can run off the main thread; this is implementation guidance, not a guarantee that a particular animation will perform well on every device.
Best Value
A practical decision check
- Is a node entering or leaving? Use
transition:; choose local or|globalscope based on which block’s creation or destruction should trigger it. - Is an existing keyed item changing index? Use
animate:on the immediate child of the keyed each block. - Does animation completion change application behavior? Listen for the corresponding Svelte lifecycle event and send an explicit event to the actor.
- Can users interrupt or reverse the effect? Define the machine’s response to interruption rather than relying on a single assumed completion path.
- Is this only visual decoration? Keep it in Svelte unless the behavior genuinely needs machine-level modeling.
- Does the effect respect reduced-motion preferences? Adjust or disable Svelte transitions through its reduced-motion facility rather than relying only on a global CSS duration override.
For a starting point, Stately’s integration documentation links to CodeSandbox and StackBlitz templates. Treat them as learning and prototyping resources, and verify that their dependencies suit the versions in your project.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

