Swapping Text

Text that swaps to a new value letter by letter, each changed letter sliding out as the new one slides in.

Design
"use client"

import {
  SwappingText,
  type SwappingTextDirection,
} from "@animate-ui/react/primitives/texts/swapping"

const WORDS = ["Design", "Develop", "Deploy"]

export default function SwappingTextDemo({
  direction = "up",
  stagger = 0.07,
  duration = 2000,
}: {
  direction?: SwappingTextDirection
  stagger?: number
  duration?: number
}) {
  return (
    <span className="inline-grid justify-items-start text-4xl font-semibold">
      {WORDS.map((word) => (
        <span
          key={word}
          aria-hidden="true"
          className="invisible col-start-1 row-start-1"
        >
          {word}
        </span>
      ))}
      <span className="col-start-1 row-start-1 w-0 whitespace-nowrap">
        <SwappingText
          text={WORDS}
          direction={direction}
          stagger={Number(stagger)}
          duration={Number(duration)}
        />
      </span>
    </span>
  )
}

Installation

npm install @animate-ui/react motion
pnpm add @animate-ui/react motion
yarn add @animate-ui/react motion
bun add @animate-ui/react motion

Usage

import { SwappingText } from '@animate-ui/react/primitives/texts/swapping';

export function Visibility({ isPublic }: { isPublic: boolean }) {
  return <SwappingText text={isPublic ? 'Public' : 'Private'} />;
}

Given an array, it swaps from one text to the next on its own, every duration milliseconds, like Rotating Text:

<SwappingText text={['Design', 'Develop', 'Deploy']} />

Animation

  • When text changes (or, given an array, every duration milliseconds), the letters are compared position by position. A letter that stays the same doesn't move; every other one swaps in place.
  • The old letter slides up by half a line, fading and blurring out, while the new one slides up from below, unblurring in, in 0.2s. direction="down" reverses both.
  • Changed letters start one after another, from left to right, stagger seconds apart (0.04s).
  • Each letter's width glides from the old letter's to the new one's, so the word grows or shrinks smoothly. Extra letters fade out to nothing.
  • <AnimateUIProvider tempo> paces the default transition.
  • Given an array, it loops back to the first text after the last, and waits while off screen or while the tab is hidden.
  • Under reduced motion, the text changes at once.
  • Screen readers read the current text once.

API Reference

SwappingText

PropTypeDefault
text
string | string[]-
duration?
number2000
delay?
number0
direction?
'up' | 'down''up'
stagger?
number0.04
transition?
Transition{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }
...props?
Omit<React.ComponentProps<'span'>, 'children'>-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/18/2026

On this page