npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rotating-text

v1.3.0

Published

3D Rotating Text Component for React

Readme

Rotating Text

Customizable 3D text hover animation. Moves on Framer Motion's springs, built in, so React is its only dependency. Respects user's Reduced Motion preferences.

See it live at rotating-text.vercel.app, with a playground to try every prop on desktop, tablet or phone.

Install

npm install --save rotating-text

Usage

text updates the content, ignoring spaces. stagger gives you control over the time between each letter. timing sets the duration of each letter animation. Timing can be a single numeric value OR a custom timing array, with a specific duration for each letter in the text (e.g. if text is OKAY, your custom timing array can look like [0.1, 0.4, 0.5, 0.1]).

You can use className and style to add further customization and styling.

import React from 'react'

import { RotatingText } from 'rotating-text'
import 'rotating-text/dist/index.css'

function MyApp() {
  return (
    <RotatingText
      text='HOVERME'
      stagger={0.1}
      timing={0.5}
      className='rotating-text'
      style={{ fontSize: '100px' }}
    />
  )
}

Props

| Prop | Type | Default | Description | | ----------- | --------------------- | ----------- | ------------------------------------------------------------------------- | | text | string | (required) | Text to animate. | | stagger | number | 0.1 | Seconds between each letter starting its animation. | | timing | number \| number[] | 0.5 | Seconds each letter's animation lasts, or one duration per letter. | | variant | 'roll' \| 'flap' | 'roll' | roll turns each letter over like a cube; flap draws split-flap tiles. | | className | string | undefined | Class name added to the outer container. | | style | React.CSSProperties | undefined | Inline styles applied to the outer container. |

When text changes on the roll, each letter that changed turns over to the new one, in the same stagger and spring as a hover, and so does any letter a wider or narrower one pushes along; letters added or removed turn in from blank or out to blank. The width eases to the new word's over the first letter's timing, so text beside it glides along instead of jumping. A shorter word keeps the old one's room until its letters have turned away. With reduced motion on the text changes at once.

Screen readers, selection and copying get the new text as soon as text changes, as one word, from an unseen copy of the text under the turning letters. A selection's highlight is drawn behind the letters in the usual colour, or a page's own ::selection background; --rt-selection sets it for the roll alone.

Split-flap tiles

variant="flap" draws every letter on its own tile, split by a seam. On hover or tap the top half of each tile falls over the seam and bounces to rest, like a departures board. When text changes, each tile flips from its old letter to its new one, so a board can count, cycle words or follow typing; tiles added or removed flip in from blank or out to blank. A space becomes a blank tile, so padding the text to one length (word.padEnd(6)) keeps a board the same number of tiles, like a real one. With reduced motion on, letters change in place without flipping.

The tiles are styled with CSS custom properties, set on className or style:

| Property | Default | Description | | ------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --rt-tile | #1d1d1f | Tile background. | | --rt-ink | inherited | Letter colour. | | --rt-seam | #000 | Colour of the seam across the middle. | | --rt-seam-width | max(1px, 0.012em) | Height of the seam. | | --rt-gap | 0.08em | Space between tiles. | | --rt-radius | 0.06em | Tile corner radius. | | --rt-padding | 0.08em 0.1em | Space around each letter inside its tile. | | --rt-tile-width | 0.62em | Minimum tile width. | | --rt-widest | M and W | Letters every tile is at least as wide as (a CSS string, such as 'W'), so new text never resizes the board. Set none to fit tiles to the text itself when it never changes. | | --rt-perspective | 3.5em | Depth of the flap's 3D fall. |

<RotatingText text='Departures' variant='flap' className='board' />
.board {
  font-size: 80px;
  --rt-tile: #182139;
  --rt-ink: #f1ece1;
}

Notes

  1. Text wrapping is currently not supported. RotatingText works best with a single word or short phrase, as spaces are ignored (in the flap variant a space is a blank tile).
  2. The text flips when the pointer moves onto it, which on a touch screen is a tap. A flip always runs to the end; hovering again mid-flip does nothing.

License

MIT © jueungrace