Morphing Text

Text that morphs from one string to the next, letters gliding to their new place.

MorphingText Primitive
"use client"

import { MorphingText } from "@animate-ui/react/primitives/texts/morphing"

const texts = [
  "MorphingText Primitive",
  "Animate your text 🚀",
  "Handles emojis 🚀✨",
  "Built with Motion ✨",
]

export default function MorphingTextDemo({
  loop = true,
  holdDelay = 2500,
}: {
  loop?: boolean
  holdDelay?: number
}) {
  return (
    <MorphingText
      key={`${loop}-${holdDelay}`}
      className="max-w-2xl text-4xl font-semibold"
      text={texts}
      loop={loop}
      holdDelay={holdDelay}
    />
  )
}

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 { MorphingText } from '@animate-ui/react/primitives/texts/morphing';

export function Tagline() {
  return <MorphingText text={['Fast', 'Accessible', 'Animated']} loop />;
}

Letters are animated one by one, so a line can break inside a word. Prefer texts short enough not to wrap.

Animation

  • Each text holds for holdDelay, then morphs into the next: letters both texts share glide to their new place (a shared layout animation), the others fade, blur (10px) and scale (0.8) in and out. Everything moves on a soft spring (stiffness: 125, damping: 25, mass: 0.4) without overshoot.
  • Emoji and accented letters stay whole.
  • The cycle pauses off screen and in a hidden tab.
  • <AnimateUIProvider tempo> paces the default spring.
  • Under reduced motion, the texts keep cycling as a plain crossfade.
  • Screen readers read the current text whole, not letter by letter. It is not a live region.

API Reference

MorphingText

PropTypeDefault
text
string | string[]-
loop?
booleanfalse
holdDelay?
number2500
delay?
number0
initial?
TargetAndTransition | VariantLabels | boolean{ opacity: 0, scale: 0.8, filter: 'blur(10px)' }
animate?
TargetAndTransition | VariantLabels | boolean{ opacity: 1, scale: 1, filter: 'blur(0px)' }
exit?
TargetAndTransition | VariantLabels{ opacity: 0, scale: 0.8, filter: 'blur(10px)' }
variants?
Variants-
transition?
Transition{ type: 'spring', stiffness: 125, damping: 25, mass: 0.4 }
inView?
booleanfalse
inViewMargin?
string'0px'
inViewOnce?
booleantrue
...props?
Omit<HTMLMotionProps<'span'>, 'children'>-

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

Last updated: 10/18/2026

On this page