React AnimeJS

React animation library

The React layer for Anime.js.

A practical reference for the hooks, declarative components, and helpers in the @shakibdshy/react-animejs package.

Getting started

Installation

Install Anime.js, then import the local React wrapper through the configured @ alias. This repository currently owns the wrapper; it is not published as a separate npm package.
bash
pnpm add @shakibdshy/react-animejs animejs
tsx
import {  useAnime,  fadeInUp,  stagger,} from '@shakibdshy/react-animejs'

Getting started

Your first animation

useAnime creates an animation after its target ref is mounted, keeps its state reactive, and reverts owned animation work when the component unmounts.
tsx
import { useAnime } from '@shakibdshy/react-animejs'
export function Welcome() {  const { ref, controls, state } = useAnime({    opacity: [0, 1],    translateY: [24, 0],    duration: 700,    ease: 'outExpo',    autoplay: false,  })
  return (    <section>      <h1 ref={ref}>Animations that flow.</h1>      <button onClick={controls.play}>Play</button>      <output>{Math.round(state.progress)}%</output>    </section>  )}

Pass Anime.js animation properties such as opacity, translateY, and rotate alongside playback settings such as duration, ease, loop, and autoplay. Use the returned controls for playback and state when the UI needs current time, progress, or play state.

Foundation

Core concepts

The library is hooks-first. Components are convenience layers where JSX makes the relationship clearer; they are not a one-for-one replacement for every hook.

Refs are targets

Attach a returned ref to the DOM element you want to animate. Hooks also accept explicit targets where their API supports it.

Controls are imperative

play, pause, restart, reverse, seek, and related methods live on controls. Keep effects in events or effects, never render.

Scopes own cleanup

AnimeProvider and AnimeScope constrain animations and clean up managed work when their React boundary unmounts.

API reference

Hooks

Each hook below includes its purpose, import/usage, a complete example, and its public options or return type.

Hook

useAnime

useAnime<T>(options?: UseAnimeOptions)

Creates and owns an Anime.js animation for a mounted DOM or SVG target. Use it as the default animation hook when a component needs reactive state and playback controls.

Usage

tsx
import { useAnime } from '@shakibdshy/react-animejs'
const animation = useAnime({  opacity: [0, 1],})

Example

tsx
const { ref, controls, state } = useAnime({  translateY: [24, 0],  opacity: [0, 1],  duration: 700,  autoplay: false,})
return (  <button ref={ref} onClick={controls.play}>    {Math.round(state.progress)}%  </button>)

Options and return type

OptionType
options?UseAnimeOptions
returnsUseAnimeReturn<T>

Hook

useAnimeTimer

useAnimeTimer(options?: UseAnimeTimerOptions)

Creates an Anime.js timer with React-safe lifecycle management. It is useful for countdowns, loops, and animation-synchronised timing.

Usage

tsx
import { useAnimeTimer } from '@shakibdshy/react-animejs'
const timer = useAnimeTimer({  duration: 1000,  loop: true,})

Example

tsx
const { count, controls, isRunning } = useAnimeTimer({  duration: 1000,  loop: true,  trackLoopCount: true,  autoplay: true,})
return (  <button onClick={controls.pause}>    {isRunning ? count : 'Paused'}  </button>)

Options and return type

OptionType
options?UseAnimeTimerOptions
trackLoopCount?boolean
autoUpdateRefs?boolean
returnsUseAnimeTimerReturn

Hook

useAnimeTimeline

useAnimeTimeline(options?, entries?)

Creates a sequenced Anime.js timeline. Define stable entries up front or add, label, sync, and call entries later through controls.

Usage

tsx
import { useAnimeTimeline } from '@shakibdshy/react-animejs'
const timeline = useAnimeTimeline(  { autoplay: false },  entries,)

Example

tsx
const { controls } = useAnimeTimeline(  { autoplay: false },  [    {      targets: titleRef,      opacity: [0, 1],      position: 0,    },    {      targets: cardRef,      translateY: [16, 0],      position: '-=200',    },  ],)
return <button onClick={controls.play}>Play</button>

Options and return type

OptionType
options?UseAnimeTimelineOptions
entries?TimelineEntry[]
positionnumber | string
returnsUseAnimeTimelineReturn

Hook

useAnimeLayout

useAnimeLayout<T>(options?: UseAnimeLayoutOptions)

Creates FLIP-style layout animation controls for a root and its changing children. Use it when you own the refs and need manual measurement or update control.

Usage

tsx
import { useAnimeLayout } from '@shakibdshy/react-animejs'
const layout = useAnimeLayout({  duration: 500,})

Example

tsx
const { ref, controls } = useAnimeLayout({  duration: 500,  ease: 'outExpo',})
useLayoutEffect(() => {  controls.update()}, [items])
return <div ref={ref}>{items.map(renderItem)}</div>

Options and return type

OptionType
options?UseAnimeLayoutOptions
duration?number
returnsUseAnimeLayoutReturn<T>

Hook

useAnimeDraggable

useAnimeDraggable<T>(options?: UseAnimeDraggableOptions)

Makes an element draggable with Anime.js physics, optional bounds, snapping, and reactive drag information.

Usage

tsx
import { useAnimeDraggable } from '@shakibdshy/react-animejs'
const draggable = useAnimeDraggable({  axis: 'x',})

Example

tsx
const { ref, isDragging, position } = useAnimeDraggable({  container: containerRef.current,  releaseStiffness: 120,  releaseDamping: 20,})
return (  <div ref={ref}>    x: {Math.round(position.x)}    {isDragging && ' dragging'}  </div>)

Options and return type

OptionType
options?UseAnimeDraggableOptions
container?HTMLElement | RefObject
snap?DraggableSnap
returnsUseAnimeDraggableReturn<T>

Hook

useAnimeOnScroll

useAnimeOnScroll<T, C>(options?: UseAnimeOnScrollOptions)

Owns an Anime.js scroll observer and exposes target and container refs, reactive scroll state, and observer controls.

Usage

tsx
import { useAnimeOnScroll } from '@shakibdshy/react-animejs'
const scroll = useAnimeOnScroll({  enter: 'bottom center',})

Example

tsx
const { ref, progress, isInView } = useAnimeOnScroll({  enter: 'bottom center',  leave: 'top center',  sync: true,})
return (  <section ref={ref}>    {isInView ? Math.round(progress * 100) : 0}%  </section>)

Options and return type

OptionType
options?UseAnimeOnScrollOptions
sync?boolean
enter? / leave?ScrollThresholdValue
pin?boolean
start? / end?ScrollThreshold ('top top' / 'top bottom')
pinSpacing?boolean
endSpacing?number (px)
axis?'y' | 'x'
anticipatePin?number (seconds)
pinType?'auto' | 'fixed' | 'sticky'
pinReparent?boolean
scrub?boolean | number
snap?number | number[]
snapDuration?number (seconds)
onRefresh?(state) => void
invalidateOnRefresh?boolean
onPin? / onUnpin?(instance) => void
returnsUseAnimeOnScrollReturn<T, C>

Hook

useAnimeControls

useAnimeControls()

Creates one shared controller that coordinates multiple useAnime animations without passing instance refs between components.

Usage

tsx
import { useAnimeControls } from '@shakibdshy/react-animejs'
const controller = useAnimeControls()

Example

tsx
const controller = useAnimeControls()
useAnime({  translateX: 120,  controller,})
useAnime({  opacity: [0, 1],  controller,})
return <button onClick={controller.restart}>Restart both</button>

Options and return type

OptionType
parametersnone
returnsAnimeController

Hook

useAnimeWAAPI

useAnimeWAAPI<T>(options?: UseAnimeWAAPIOptions)

Runs Web Animations API work through a React hook while preserving the familiar controls and lifecycle cleanup.

Usage

tsx
import { useAnimeWAAPI } from '@shakibdshy/react-animejs'
const animation = useAnimeWAAPI({  keyframes: [{ opacity: 0 }, { opacity: 1 }],})

Example

tsx
const { ref, controls } = useAnimeWAAPI({  keyframes: [    { transform: 'scale(.96)' },    { transform: 'scale(1)' },  ],  duration: 300,  autoplay: false,})
return <button ref={ref} onClick={controls.play}>Open</button>

Options and return type

OptionType
options?UseAnimeWAAPIOptions
keyframes?Keyframe[]
returnsUseAnimeWAAPIReturn<T>

Hook

useAnimeScope

useAnimeScope<T>(options?: UseAnimeScopeOptions<T>)

Creates an Anime.js scope with cleanup, scoped selectors, shared defaults, and media-query-aware reactivity.

Usage

tsx
import { useAnimeScope } from '@shakibdshy/react-animejs'
const scope = useAnimeScope({  root: rootRef,})

Example

tsx
const { ref, scope } = useAnimeScope({  mediaQueries: {    desktop: '(min-width: 768px)',  },  defaults: {    duration: 600,  },})
return (  <section ref={ref}>    {scope.current?.matches.desktop && 'Desktop'}  </section>)

Options and return type

OptionType
options?UseAnimeScopeOptions<T>
mediaQueries?ScopeMediaQueries
returnsUseAnimeScopeReturn<T>

Hook

useSplitText

useSplitText(options?: UseSplitTextOptions)

Splits a text target into characters, words, or lines and gives you the Anime.js TextSplitter plus safe lifecycle methods.

Usage

tsx
import { useSplitText } from '@shakibdshy/react-animejs'
const split = useSplitText({  chars: true,})

Example

tsx
const { ref, split, isReady } = useSplitText({  chars: true,  words: true,})
useEffect(() => {  if (isReady) {    animate(split.current?.chars, {      opacity: [0, 1],    })  }}, [isReady])
return <h1 ref={ref}>Hello</h1>

Options and return type

OptionType
options?UseSplitTextOptions
chars? / words? / lines?boolean
returnsUseSplitTextReturn

Hook

useAnimatable

useAnimatable<T>(config)

Creates a reactive Anime.js animatable value for DOM elements or arbitrary compatible objects.

Usage

tsx
import { useAnimatable } from '@shakibdshy/react-animejs'
const value = useAnimatable({ initial: 0 })

Example

tsx
const progress = useAnimatable({ initial: 0 })
return <input  type="range"  onChange={(event) => progress.set(Number(event.target.value))}/>

Options and return type

OptionType
configAnimatableConfig
initialnumber | string
returnsUseAnimatableReturn<T>

Hook

useAnimatableEvent

useAnimatableEvent(event, handler)

Binds an event handler to an HTMLElement event with the same stable lifecycle conventions as the rest of the library.

Usage

tsx
import { useAnimatableEvent } from '@shakibdshy/react-animejs'
useAnimatableEvent('pointermove', onMove)

Example

tsx
const ref = useRef<HTMLDivElement>(null)useAnimatableEvent(ref, 'pointermove', (event) => {  pointer.set(event.clientX)})
return <div ref={ref} />

Options and return type

OptionType
targetRefObject<HTMLElement>
eventkeyof HTMLElementEventMap
handlerEventListener

Hook

useAnimeAdapter

useAnimeAdapter(config: AnimeAdapterConfig)

Registers a React-managed Anime.js adapter so custom objects, canvas primitives, or render-engine values can be targeted.

Usage

tsx
import { useAnimeAdapter } from '@shakibdshy/react-animejs'
useAnimeAdapter({  id: 'canvas',  detect,  targets,})

Example

tsx
useAnimeAdapter({  id: 'sprite',  detect: (value) => value?.kind === 'sprite',  targets: [    {      detect: () => true,      properties: {        x: {          get: (sprite) => sprite.x,          set: (sprite, value) => {            sprite.x = value          },        },      },    },  ],})

Options and return type

OptionType
configAnimeAdapterConfig
idstring
targetsAnimeAdapterTarget[]
returnsUseAnimeAdapterReturn

Hook

useSvgAnimation

useSvgAnimation<TSvg>(options: SvgAnimationOptions)

Provides shared target refs, playback controls, and cleanup for custom SVG animation components.

Usage

tsx
import { useSvgAnimation } from '@shakibdshy/react-animejs'
const svg = useSvgAnimation({  createConfig,})

Example

tsx
const { childRef, controls } = useSvgAnimation<SVGPathElement>({  createConfig: (target) => ({    targets: target,    strokeDashoffset: [100, 0],  }),})
return <path ref={childRef} onClick={controls.play} />

Options and return type

OptionType
optionsSvgAnimationOptions
createConfig(target) => object
returnsSvgComponentRef

Hook

useAnimeScramble

useAnimeScramble(options: UseAnimeScrambleOptions)

Controls Anime.js text scrambling as a React hook, including automatic cleanup and a stable update method.

Usage

tsx
import { useAnimeScramble } from '@shakibdshy/react-animejs'
const scramble = useAnimeScramble({  text: 'Ready',})

Example

tsx
const { ref, scramble } = useAnimeScramble({  text: 'Build in motion',  duration: 650,  autoplay: false,})
return (  <button ref={ref} onMouseEnter={() => scramble()}>    Build in motion  </button>)

Options and return type

OptionType
optionsUseAnimeScrambleOptions
textstring
returnsUseAnimeScrambleReturn

API reference

Components

Components intentionally cover both hook-backed and composition patterns. Each entry documents its own API instead of implying every component is a hook wrapper.

Component

AnimeProvider

<AnimeProvider>{children}</AnimeProvider>

Provides a shared scope context so descendant hooks can resolve scoped targets and clean up together.

Usage

tsx
import { AnimeProvider } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeProvider>  <PageWithScopedAnimations /></AnimeProvider>

Props

PropType
children*ReactNode

Component

Anime

<Anime {...animationProps}>

A declarative single-target animation wrapper built on useAnime. It forwards a ref to its child target and accepts animation options.

Usage

tsx
import { Anime } from '@shakibdshy/react-animejs'

Example

tsx
<Anime  opacity={[0, 1]}  translateY={[16, 0]}  duration={500}  autoplay>  <h2>Visible in JSX</h2></Anime>

Props

PropType
children*ReactElement
autoplay?boolean | ScrollObserverParams
onStateChange?(state) => void

Component

AnimeScroll

<AnimeScroll {...scrollOptions}>{render}</AnimeScroll>

A render-prop wrapper around useAnimeOnScroll that adds no target wrapper element.

Usage

tsx
import { AnimeScroll } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeScroll  enter="bottom center"  sync>  {({ ref, progress }) => (    <div ref={ref}>{Math.round(progress * 100)}%</div>  )}</AnimeScroll>

Props

PropType
childrenReactNode | (api) => ReactNode
enter? / leave?ScrollThresholdValue
pin?boolean
onReady?(api) => void

Component

AnimeBatch

<AnimeBatch animation={...}>{children}</AnimeBatch>

Observes descendants marked with data-anime-batch and animates them in short, configurable viewport batches.

Usage

tsx
import { AnimeBatch } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeBatch  animation={{    opacity: [0, 1],    translateY: [12, 0],  }}>  <Card data-anime-batch />  <Card data-anime-batch /></AnimeBatch>

Props

PropType
children*ReactNode
animation*AnimeBatchAnimation
batchSize?number

Component

AnimeDraw

<AnimeDraw {...animationProps}>

Draws a compatible SVG shape by animating its drawable path values through useSvgAnimation.

Usage

tsx
import { AnimeDraw } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeDraw  strokeDashoffset={[1, 0]}  duration={900}>  <path d="M0 20 L100 20" /></AnimeDraw>

Props

PropType
children*ReactElement
autoplay?boolean
duration?number

Component

AnimeMorph

<AnimeMorph to="...">

Morphs a supported SVG path to a new shape using the shared SVG animation lifecycle.

Usage

tsx
import { AnimeMorph } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeMorph  to="M10 10 H90 V90 H10 Z"  duration={700}>  <path d="M50 10 L90 90 H10 Z" /></AnimeMorph>

Props

PropType
children*ReactElement
to*string | SVGPathElement
duration?number

Component

AnimeMotionPath

<AnimeMotionPath path="...">

Moves an SVG element along an SVG path while exposing the familiar playback controls through its ref.

Usage

tsx
import { AnimeMotionPath } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeMotionPath  path="#orbit"  duration={1600}>  <circle r="6" /></AnimeMotionPath>

Props

PropType
children*ReactElement
path*string | SVGPathElement
rotate?boolean | number

Component

AnimePresence

<AnimePresence mode="sync">

Coordinates enter and exit animation for keyed direct children using AnimePresenceChild.

Usage

tsx
import { AnimePresence, AnimePresenceChild } from '@shakibdshy/react-animejs'

Example

tsx
<AnimePresence mode="wait">  {open && (    <AnimePresenceChild      key="panel"      enter={{ opacity: [0, 1] }}      exit={{ opacity: [1, 0] }}    >      <Panel />    </AnimePresenceChild>  )}</AnimePresence>

Props

PropType
children*ReactNode
mode?sync | wait | popLayout
initial?boolean
onExitComplete?() => void

Component

AnimePresenceChild

<AnimePresenceChild enter={...} exit={...}>

Defines the enter and exit animation for one keyed child managed by AnimePresence.

Usage

tsx
import { AnimePresenceChild } from '@shakibdshy/react-animejs'

Example

tsx
<AnimePresenceChild  key="notice"  enter={{ opacity: [0, 1] }}  exit={{    opacity: [1, 0],    translateY: 12,  }}>  <Notice /></AnimePresenceChild>

Props

PropType
children*ReactElement
enter?UseAnimeOptions
exit?UseAnimeOptions

Component

AnimeLayout

<AnimeLayout>{children}</AnimeLayout>

Declarative FLIP layout container built on useAnimeLayout. Pair it with AnimeLayout.Item for list, grid, and reorder transitions.

Usage

tsx
import { AnimeLayout } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeLayout  duration={500}  autoAnimate>  {items.map((item) => (    <AnimeLayout.Item key={item.id} id={item.id}>      <Card item={item} />    </AnimeLayout.Item>  ))}</AnimeLayout>

Props

PropType
children*ReactNode
autoAnimate?boolean
enterFrom? / leaveTo?AnimeLayoutStateParams
onReady?(api) => void

Component

AnimeLayout.Item

<AnimeLayout.Item id="...">

Registers one stable child with its parent AnimeLayout. The id makes movement across renders identifiable.

Usage

tsx
import { AnimeLayout } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeLayout.Item id={item.id}>  <Card item={item} /></AnimeLayout.Item>

Props

PropType
id*string
children*ReactElement
as?ElementType

Component

AnimeTimeline

<AnimeTimeline entries={...}>{children}</AnimeTimeline>

Declarative timeline provider built on useAnimeTimeline. Children can be static or a render function receiving controls and state.

Usage

tsx
import { AnimeTimeline } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeTimeline  autoplay={false}  entries={entries}>  {({ controls }) => (    <button onClick={controls.play}>Play sequence</button>  )}</AnimeTimeline>

Props

PropType
entries?TimelineEntry[]
children?ReactNode | (api) => ReactNode
onReady?(api) => void
onStateChange?(state) => void

Component

AnimeWAAPI

<AnimeWAAPI {...waapiOptions}>

Declarative Web Animations API component built on useAnimeWAAPI.

Usage

tsx
import { AnimeWAAPI } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeWAAPI  keyframes={[    { opacity: 0 },    { opacity: 1 },  ]}  duration={240}>  <div>Native animation</div></AnimeWAAPI>

Props

PropType
children*ReactElement
keyframes?Keyframe[]
onReady?(api) => void

Component

AnimeAdapter

<AnimeAdapter id="..." detect={...}>

Registers a custom adapter declaratively and renders no extra DOM node.

Usage

tsx
import { AnimeAdapter } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeAdapter id="sprite" detect={(value) => value?.kind === 'sprite'} targets={targets}>  <CanvasScene /></AnimeAdapter>

Props

PropType
id*string
detect*(value) => boolean
targets*AnimeAdapterTarget[]
children?ReactNode

Component

AnimeScope

<AnimeScope animate={...}>{children}</AnimeScope>

Declarative scope boundary built on useAnimeScope. It can provide defaults, react to media queries, and expose registered methods.

Usage

tsx
import { AnimeScope } from '@shakibdshy/react-animejs'

Example

tsx
<AnimeScope animate={({ animate }) => animate('.item', { opacity: [0, 1] })}>  <div className="item" /></AnimeScope>

Props

PropType
children*ReactNode | (matches) => ReactNode
animate?AnimeScopeAnimateFn
mediaQueries?ScopeMediaQueries
defaults?ScopeDefaults

Component

SplitText

<SplitText params={...}>{children}</SplitText>

Declarative text splitting component with a ref API for split, revert, refresh, and the TextSplitter instance.

Usage

tsx
import { SplitText } from '@shakibdshy/react-animejs'

Example

tsx
<SplitText params={{ chars: true, words: true }} onReady={(split) => console.log(split.chars)}>  <h1>Animate every character</h1></SplitText>

Props

PropType
children*ReactElement
params?TextSplitterParams
onReady?(split) => void

Component

SplitTextEntry

<SplitTextEntry splitRef={...} splitMode="chars" />

Registers one declarative text-animation entry with a parent AnimeTimeline after the splitter is ready.

Usage

tsx
import { SplitTextEntry } from '@shakibdshy/react-animejs'

Example

tsx
<SplitTextEntry  splitRef={titleRef}  splitMode="chars"  opacity={[0, 1]}  translateY={[20, 0]}  stagger={30}/>

Props

PropType
splitRef*RefObject<SplitTextRef>
splitMode*chars | words | lines
stagger?number
position?number | string
enabled?boolean

Helpers

Utilities

Utilities are public developer tools, not implementation details. Use them to make repeated animation values expressive and consistent.

Presets

Use fadeIn, fadeOut, directional fades, scale and slide presets, plus pulse, bounce, shake, wiggle, heartbeat, flips, rotateIn, and spin. getPreset(name) looks up a typed preset.

Stagger helpers

Choose simple, center, last, edges, indexed, grid X/Y, ripple, eased, in/out, random, or custom staggering. stagger mirrors the library helper; createStagger enables configuration.

tsx
import { fadeInUp, gridStagger, clamp, lerp } from '@shakibdshy/react-animejs'
const cardAnimation = {  ...fadeInUp,  delay: gridStagger(80, 3, 2),}
const safeProgress = clamp(progress, 0, 1)const translateX = lerp(0, 120, safeProgress)

The general helper exports are $, get, set, cleanInlineStyles, remove, sync, keepTime, random and seeded-random helpers, shuffle, round, clamp, snap, wrap, mapRange, lerp, damp, padding helpers, and degree/radian conversion.

Reference

Anime.js exports

The package also re-exports carefully selected Anime.js primitives for advanced cases. This keeps a single import path when the React abstraction is not the right tool.

Available exports include animate, createTimer, createTimeline, createLayout, createAnimatable, createScope, createDraggable, SVG factories, onScroll, morphTo, easing constructors, engine, waapi, events, splitText, scrambleText, and adapter registration.

Reference

TypeScript and cleanup

Exported options, returns, instance types, easing types, timeline types, layout types, draggable types, scroll types, scope types, adapter types, and component prop/ref types are available from the same entry point.
tsx
import type {  UseAnimeOptions,  UseAnimeReturn,  AnimeTimelineRef,  UseAnimeOnScrollOptions,} from '@shakibdshy/react-animejs'

Let the hook own the animation lifecycle whenever possible. If you create raw Anime.js instances yourself, clean them up in an effect cleanup function. Keep callbacks stable when they drive React state, and use refs or throttling for frame-level updates.