@tasul/shuffle-text
v2.0.0
Published
Zero-dependency vanilla-JS/TS library for text switching effects
Maintainers
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.

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:
- React →
@tasul/shuffle-text-react - Vue 3 →
@tasul/shuffle-text-vue
Install
npm i @tasul/shuffle-textShips 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 stepHow 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 spansinline/inline-blockso 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.
textArraymust be non-empty, and needs 2+ entries forplay()/ the auto loop to morph between strings.replaceTimedefault is50. (It was100in the original 1.x; 2.0 standardizes on the documented50. PassreplaceTime: 100to restore the old speed.)
License
MIT © tasul
