Anime.js logo

Anime.js

A lightweight animation engine that excels at complex timelines, SVG manipulation, and choreographed sequences.

npm install animejs
65.3K305.1K/weekv4.2.21.48 MBMIT88 issues
Last updated: 2025-10-07
Star history chart for juliangarnier/anime

TL;DR

A framework-agnostic JavaScript animation library known for its powerful timeline API and staggering capabilities.

While imperative by nature, it offers a level of granular control over complex sequences and SVG paths that is unmatched by React-specific alternatives.

Why Anime.js?

Anime.js is not a React library; it is a JavaScript animation engine. However, it remains a top choice for React developers building "Creative Web" experiences—think award-winning landing pages or complex data visualizations. Its imperative nature allows for precise orchestration that can be difficult to express declaratively.

  • Masterful Timelines: The .timeline() API allows you to chain dozens of animations together, offset them relative to one another, and control the entire sequence (play, pause, reverse, seek) with a single object.
  • SVG Superpowers: It has best-in-class support for SVG path morphing, line drawing (dash-offset animation), and motion path animation out of the box.
  • Staggering System: The stagger helper is incredibly powerful, allowing you to ripple animations across grids, lists, or radial patterns with minimal code.
  • Lightweight: At roughly 6kb (gzipped), it provides a massive feature set without bloating your bundle.
  • Granular Control: You can animate CSS properties, SVG attributes, DOM attributes, and even JavaScript objects interchangeably.

Code Snippet

Since Anime.js is imperative, you must use useRef to target elements and useEffect to trigger the animation. This example creates a Timeline that draws an SVG stroke and then fills it.

import React, { useEffect, useRef } from 'react';
import anime from 'animejs';

export const LogoAnimation = () => {
  const svgRef = useRef(null);
  const pathRef = useRef(null);

  useEffect(() => {
    // Create a timeline
    const tl = anime.timeline({
      easing: 'easeOutExpo',
      duration: 750
    });

    // Sequence the animations
    tl.add({
      targets: pathRef.current,
      strokeDashoffset: [anime.setDashoffset, 0], // Draw the line
      duration: 1500,
    })
    .add({
      targets: svgRef.current,
      opacity: [0, 1], // Fade in container
      scale: [0.8, 1],
    }, '-=500'); // Overlap by 500ms

    // Cleanup to prevent memory leaks
    return () => tl.pause();
  }, []);

  return (
    <div ref={svgRef} style={{ opacity: 0 }}>
      <svg width="100" height="100" viewBox="0 0 100 100">
        <path
          ref={pathRef}
          d="M10 10 H 90 V 90 H 10 L 10 10"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
        />
      </svg>
    </div>
  );
};

Notice the '-=500' offset string. This ability to overlap animations on a timeline relative to the previous one is a signature feature of Anime.js.

Pros and Cons

No library is perfect; understanding the trade-offs is key to selecting the right tool.

Pros

  • Sequencing: Creating complex "movies" or intros where multiple elements interact is significantly easier than with declarative hooks.
  • SVG Support: If you need to morph shapes or animate along a path, Anime.js handles the math for you.
  • Curve Control: It supports custom cubic-bezier curves, spring physics, and elastic easings, giving you full control over the "feel."

Cons

  • React Friction: You have to manually manage refs and useEffect. It fights against React's declarative nature (e.g., if React unmounts the component while an animation is playing, you must handle cleanup manually).
  • No Exit Transitions: Unlike Framer Motion's AnimatePresence, Anime.js has no built-in concept of "animating out" when a component is removed from the DOM.
  • Imperative State: You are often synchronizing two sources of truth: React's state and Anime.js's internal animation state.

Comparison with Other Animation Libraries

The table below outlines the positioning differences between Anime.js and other popular animation libraries to help you make an informed decision:

LibraryDesign PhilosophyBest ForPain Points
Anime.jsImperative Timeline
Chainable methods to orchestrate precise sequences.
Creative & SVG
Intro sequences, complex SVG morphing, and canvas animations.
React Integration
Requires boilerplate (useRef/useEffect); hard to handle component unmounting.
Framer MotionDeclarative State
Define states (open, closed) and let the library interpolate.
App UI
Interactive interfaces, layout transitions, and shared element animations.
Sequencing
Complex, multi-step timelines across different components can be verbose to wire up.
React SpringPhysics Simulation
Fluid, interruptible motion based on spring dynamics.
Natural Interaction
Drag gestures and UI elements that need to feel physical.
Orchestration
Chaining multiple animations together is difficult compared to a timeline.

Verdict: When to Adopt

Anime.js is a specialized tool. Use it when you are building a "Creative" experience—like a storytelling page, a game intro, or a complex data visualization—where the animation is the content. Its timeline and SVG capabilities are unmatched in this domain.

However, for standard application UI (modals, sidebars, list filtering), avoid it. Framer Motion will save you hours of headache by handling mounting/unmounting logic and state synchronization automatically.