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

@tasul/shuffle-text

v2.0.0

Published

Zero-dependency vanilla-JS/TS library for text switching effects

Readme

@tasul/shuffle-text

A tiny, zero-dependency library for text-switching / morphing effects. It takes an element and cycles its text through a list of strings, swapping the characters one slot at a time — like a split-flap board or a "scramble" reveal.

ShuffleText demo

The four rows above are the four recipes in Options.

Works in any browser. No framework required. Using React or Vue? Reach for the official wrappers instead — they handle mounting and cleanup for you:


Install

npm i @tasul/shuffle-text

Ships as ESM, CommonJS, and a browser <script> global — use whichever fits.

Quick start

<div class="headline"></div>
import { ShuffleText } from '@tasul/shuffle-text';

const shuffle = new ShuffleText('.headline', {
  textArray: ['Hello', 'Yo!', '¡Hola!', 'Salut', 'Ciao', '안녕하세요', 'こんにちは'],
  isAuto: true, // start looping immediately
});

That's it — the headline now cycles through the list forever. To drive it manually instead, leave isAuto off and call play() on your own events:

const shuffle = new ShuffleText('.headline', {
  textArray: ['Menu', 'Close'],
});

button.addEventListener('click', () => shuffle.play()); // advance one step

How it renders (and how to style it)

Each visible character is wrapped in its own <span>. So after a morph the DOM looks like:

<div class="headline"><span>Y</span><span>o</span><span>!</span></div>

That per-character markup is the hook for CSS: target the spans to add a transition, color flicker, blur, etc.

.headline span {
  display: inline-block;
  transition: opacity 0.15s, transform 0.15s;
}

Whitespace note: spaces become <span> </span>. If you rely on spacing, keep the spans inline/inline-block so the whitespace renders.

Options

Pass as the second constructor argument. Only textArray is required.

| Option | Type | Default | Description | | :--- | :--- | :--- | :--- | | textArray | string[] | — (required, non-empty) | The strings to cycle through. Use two or more for a visible morph. | | isAuto | boolean | false | Start the auto loop right after construction. | | isReplacedRandomly | boolean | false | Animate the character slots in a random order instead of left-to-right. | | isDisorderedArray | boolean | false | Shuffle the order of the strings once, at construction. | | stayTime | number | 1500 | Pause (ms) on a finished word before morphing to the next (auto loop only). | | replaceTime | number | 50 | Time (ms) between each character swap. Lower = faster morph. |

The four classic recipes

// 1. Auto loop, characters swap left-to-right
new ShuffleText('.t1', { textArray: WORDS, isAuto: true });

// 2. Auto loop, characters swap in random order (more chaotic)
new ShuffleText('.t2', { textArray: WORDS, isAuto: true, isReplacedRandomly: true });

// 3. Auto loop, but the word order itself is shuffled once up front
new ShuffleText('.t3', { textArray: WORDS, isAuto: true, isDisorderedArray: true });

// 4. Both: random word order AND random character order
new ShuffleText('.t4', {
  textArray: WORDS,
  isAuto: true,
  isReplacedRandomly: true,
  isDisorderedArray: true,
});

Methods

const shuffle = new ShuffleText(target, options);

| Method | Signature | Description | | :--- | :--- | :--- | | play | () => void | Morph once to the next string in the list. | | playAuto | () => void | Start the auto loop. Attach it to any event (e.g. on hover, on scroll-into-view). | | clear | () => void | Stop the auto loop and the morph timers. Always call this to tear an instance down (e.g. before removing the element). |

// Start on hover, stop on leave
el.addEventListener('mouseenter', () => shuffle.playAuto());
el.addEventListener('mouseleave', () => shuffle.clear());

TypeScript

Types ship with the package — no @types needed.

import { ShuffleText, type ShuffleOptions, type ShuffleTarget } from '@tasul/shuffle-text';

// target is a CSS selector string OR an HTMLElement you already have
const el: ShuffleTarget = document.querySelector('.headline')!;
const opts: ShuffleOptions = { textArray: ['a', 'b'], isAuto: true };
new ShuffleText(el, opts);

Use via <script> tag (no bundler)

A prebuilt global bundle is published at the unpkg path and exposes ShuffleText on window:

<div class="headline"></div>
<script src="https://unpkg.com/@tasul/shuffle-text"></script>
<script>
  new ShuffleText('.headline', { textArray: ['Hello', 'World'], isAuto: true });
</script>

Good to know

  • Browser only. It reads the DOM (document.querySelector, innerHTML), so it does not run under Node/SSR. In SSR frameworks, construct it after mount.
  • The target must already exist when you construct — a selector that matches nothing throws a clear error.
  • textArray must be non-empty, and needs 2+ entries for play() / the auto loop to morph between strings.
  • replaceTime default is 50. (It was 100 in the original 1.x; 2.0 standardizes on the documented 50. Pass replaceTime: 100 to restore the old speed.)

License

MIT © tasul