New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

unicode-animations

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unicode-animations

Unicode spinner animations as raw frame data

latest
Source
npmnpm
Version
1.0.3
Version published
Weekly downloads
11K
29.58%
Maintainers
1
Weekly downloads
 
Created
Source

unicode-animations

Unicode spinner animations as raw frame data — no dependencies, works everywhere.

Demo

See all 18 spinners animating live:

npx unicode-animations --web     # open browser demo
npx unicode-animations           # cycle through all in terminal
npx unicode-animations helix     # preview a specific spinner
npx unicode-animations --list    # list all spinners

Install

npm install unicode-animations

Quick start

// ESM
import spinners from 'unicode-animations';

// CJS
const spinners = require('unicode-animations');

Each spinner is a { frames: string[], interval: number } object.

Examples

CLI tool — spinner during async work

import spinners from 'unicode-animations';

const { frames, interval } = spinners.braille;
let i = 0;

const spinner = setInterval(() => {
  process.stdout.write(`\r\x1B[2K  ${frames[i++ % frames.length]} Deploying to production...`);
}, interval);

await deploy();

clearInterval(spinner);
process.stdout.write('\r\x1B[2K  ✔ Deployed.\n');

Reusable spinner helper

import spinners from 'unicode-animations';

function createSpinner(msg, name = 'braille') {
  const { frames, interval } = spinners[name];
  let i = 0, text = msg;
  const timer = setInterval(() => {
    process.stdout.write(`\r\x1B[2K  ${frames[i++ % frames.length]} ${text}`);
  }, interval);

  return {
    update(msg) { text = msg; },
    stop(msg) { clearInterval(timer); process.stdout.write(`\r\x1B[2K  ✔ ${msg}\n`); },
  };
}

const s = createSpinner('Connecting to database...');
const db = await connect();
s.update(`Running ${migrations.length} migrations...`);
await db.migrate(migrations);
s.stop('Database ready.');

Multi-step pipeline

import spinners from 'unicode-animations';

async function runWithSpinner(label, fn, name = 'braille') {
  const { frames, interval } = spinners[name];
  let i = 0;
  const timer = setInterval(() => {
    process.stdout.write(`\r\x1B[2K  ${frames[i++ % frames.length]} ${label}`);
  }, interval);
  const result = await fn();
  clearInterval(timer);
  process.stdout.write(`\r\x1B[2K  ✔ ${label}\n`);
  return result;
}

await runWithSpinner('Linting...', lint, 'scan');
await runWithSpinner('Running tests...', test, 'helix');
await runWithSpinner('Building...', build, 'cascade');
await runWithSpinner('Publishing...', publish, 'braille');

React component

import { useState, useEffect } from 'react';
import spinners from 'unicode-animations';

function Spinner({ name = 'braille', children }) {
  const [frame, setFrame] = useState(0);
  const s = spinners[name];

  useEffect(() => {
    const timer = setInterval(
      () => setFrame(f => (f + 1) % s.frames.length),
      s.interval
    );
    return () => clearInterval(timer);
  }, [name]);

  return <span style={{ fontFamily: 'monospace' }}>{s.frames[frame]} {children}</span>;
}

// Usage: <Spinner name="helix">Generating response...</Spinner>

Browser — status indicator

import spinners from 'unicode-animations';

const el = document.getElementById('status');
const { frames, interval } = spinners.orbit;
let i = 0;

const spinner = setInterval(() => {
  el.textContent = `${frames[i++ % frames.length]} Syncing...`;
}, interval);

await sync();
clearInterval(spinner);
el.textContent = '✔ Synced';

All spinners

Classic braille

NamePreviewInterval
braille⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏80ms
braillewave⠁⠂⠄⡀⠂⠄⡀⢀100ms
dna⠋⠉⠙⠚⠉⠙⠚⠒80ms

Grid animations (braille)

NameFramesInterval
scan1070ms
rain12100ms
scanline6120ms
pulse5180ms
snake1680ms
sparkle6150ms
cascade1260ms
columns2660ms
orbit8100ms
breathe17100ms
waverows1690ms
checkerboard4250ms
helix1680ms
fillsweep11100ms
diagswipe1660ms

Custom spinners

Create your own braille spinners using the grid utilities:

import { gridToBraille, makeGrid } from 'unicode-animations';

// Create a 4-row × 4-col grid
const grid = makeGrid(4, 4);
grid[0][0] = true;
grid[1][1] = true;
grid[2][2] = true;
grid[3][3] = true;

console.log(gridToBraille(grid)); // diagonal braille pattern

makeGrid(rows, cols) returns a boolean[][]. Set cells to true to raise dots. gridToBraille(grid) converts it to a braille string (2 dot-columns per character).

API

Spinner

interface Spinner {
  readonly frames: readonly string[];
  readonly interval: number;
}

Exports from 'unicode-animations'

ExportType
default / spinnersRecord<BrailleSpinnerName, Spinner>
gridToBraille(grid)(boolean[][]) => string
makeGrid(rows, cols)(number, number) => boolean[][]
SpinnerTypeScript interface
BrailleSpinnerNameUnion type of all 18 spinner names

Exports from 'unicode-animations/braille'

Same as above — the main entrypoint re-exports everything from the braille module.

License

MIT

Keywords

braille

FAQs

Package last updated on 16 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts