Skip to main content
View Zag.js on Github
Join the Discord server


The presence machine is a state machine that helps you manage exit animations in your project.

In the DOM, when a component is removed from the tree or hidden, it's removed instantly. The presence machine suspends the component to allow its exit animation before removing or hiding it.

The presence machine requires using CSS animations to animate the component's exit.

Open true, Unmounted: false


To use the presence machine in your project, run the following command in your command line:

npm install @zag-js/presence @zag-js/react # or yarn add @zag-js/presence @zag-js/react

This command will install the framework agnostic presence logic and the reactive utilities for your framework of choice.


First, import the presence package into your project

import * as presence from "@zag-js/presence"

The presence package exports two key functions:

  • machine — The state machine logic for the presence.
  • connect — The function that translates the machine's state to JSX attributes and event handlers.

Next, import the required hooks and functions for your framework and use the presence machine in your project 🔥

import * as presence from "@zag-js/presence" import { useMachine, normalizeProps } from "@zag-js/react" interface PresenceProps { present: boolean unmountOnExit?: boolean onExitComplete?: () => void } function Presence(props: PresenceProps) { const { unmountOnExit, present, onExitComplete, } = props const [state, send] = useMachine(presence.machine({ present }), { context: { present, onExitComplete }, }) const api = presence.connect(state, send, normalizeProps) if (!api.present && unmountOnExit) return null return ( <div hidden={!api.present} data-state={api.skip ? undefined : present ? "open" : "closed"} ref={api.setNode} {} /> ) }

Styling guide

To style any entry and exit animations, set up the @keyframes and apply the animations.

@keyframes enter { from { scale: 0.9; opacity: 0; } to { opacity: 1; scale: 1; } } @keyframes exit { to { opacity: 0; scale: 0.9; } } [data-state="open"] { animation: enter 0.15s ease-out; } [data-state="closed"] { animation: exit 0.1s ease-in; }

You can then use the Presence component in your project.

function Example() { const [open, setOpen] = React.useState(true) return ( <> <button onClick={() => setOpen((c) => !c)}>Toggle</button> <Presence present={open} unmountOnExit> <div>Content</div> </Presence> </> ) }

Methods and Properties

Machine Context

The presence machine exposes the following context properties:

  • presentbooleanWhether the node is present (controlled by the user)
  • onExitComplete() => voidFunction called when the animation ends in the closed state.

Machine API

The presence api exposes the following methods:

  • skipbooleanWhether the animation should be skipped.
  • presentbooleanWhether the node is present in the DOM.
  • setNode(node: HTMLElement) => voidFunction to set the node (as early as possible)
  • unmount() => voidFunction to programmatically unmount the node

Edit this page on GitHub

Proudly made in🇳🇬by Segun Adebayo

Copyright © 2024
On this page