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

react-strp-counter

v1.1.1

Published

A lightweight counter that relies on CSS to rearrange numbers and doesn't rerender Elements

Readme

react-strp-counter

A high-performance, CSS-only animated counter for React that never re-renders on value updates.

Ideal for dashboards, KPIs, and animated counters where performance and visual smoothness matter.

LIGHT Package Size:

minzip size

Demo: https://stripearmy.github.io/strp-counter-demo/


✨ Features

  • ⚡ Zero re-renders — DOM is fully static after mount
  • 🔁 2 modes:
    • Static: Only changed digits animate
    • Rolling: Seamless jackpot-style rolling using duplicated digit strings
  • 🧩 Accepts numbers or formatted strings
  • 🏷 Optional unit label with positioning
  • 🧠 Ripple-style animation with dynamic delay per digit

How It Works

This component avoids React re-renders by offloading all animation logic to CSS variables and direct DOM manipulation. Every digit is pre-rendered via CSS content (:before) and animated with transform.

In rolling mode, digits animate smoothly from their current index to index + 10 (which wraps visually), and snap back after the transition ends.


📦 Installation

npm install react-strp-counter

or

yarn add react-strp-counter

🚀 Usage

// import STRPCounter
import {STRPCounter} from 'react-strp-counter';
// import CSS
import 'react-strp-counter/css';

<STRPCounter
    value={1234567.89} // REQUIRED
    fontSize="48px" // optional
    minLength={9} // optional
    delimiter="," // optional
    decimalSeparator="." // optional
    unitLabel="USD" // optional
    unitLabelPosition="left" // optional
    rollingMode={true} // optional
    stepDuration={0.05} // optional
    easing={"cubic-bezier(0.33,0.81,0.1,1.02)"} // optional
/>

🧩 Props

| Prop | Type | Required | Default | Description | |---------------------|-----------------------------|----------|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | value | number \| string | ✅ | — | The numeric value or formatted string to render | | fontSize | string | ❌ | "28px" | Font size (used as --strp_fontsize CSS variable) | | minLength | number | ❌ | — | Pad with zeroes on the left to reach minimum character length, used to avoid layout shifts when your number has to add a digit from the left side, optional, but I highly suggest to always use this | | rollingMode | boolean | ❌ | false | If true, enables jackpot-style rolling animation | | stepDuration | number | ❌ | 0.05 | Optional, used with rollingMode, Per-digit step duration (in seconds) used for timing delays | | delimiter | string \| false | ❌ | false | Thousands delimiter (e.g. ",", " ") | | decimalSeparator | string \| false | ❌ | false | Decimal point (e.g. "."), always add 2 decimals if you use this | | unitLabel | string \| React.ReactNode | ❌ | — | Optional unit (e.g. "$", "kg", "<div />", "<svg />" etc.) | | unitLabelPosition | 'left' \| 'right' | ❌ | "left" | Where to place the unit label | | easing | string \| false | ❌ | "cubic-bezier(0.33, 0.81, 0.1, 1.02)" | If set to "false" component will use "linear" instead. Feel free to pass your custom easing |


🧠 Best Practices

Use tabular fonts (e.g. Roboto Mono, JetBrains Mono, Menlo, SF Mono) for perfect alignment.

Font used in demo is Big Shoulders Stencil


🎨 Styling (Bring Your Own FONT)

You are required to supply your own FONT.

The package does not include any fonts to make it as lightweight as possible.

Code below:

.strp_counter_wrap {
    --strp_fontfamily: 'YOUR CUSTOM FONT FAMILY';
}

or

:root {
    --strp_fontfamily: 'YOUR CUSTOM FONT FAMILY';
}

🎨 Styling (for RTL users)

Everything inside the component is forced to render in LTR state, if you supply a RTL unitLabel please force it to be rendered as RTL

.strp_counter_wrap .YOUR_CUSTOM_UNITLABEL {
    direction: rtl !important;
}

Animation Modes

1. Default Mode (rollingMode: false)

  • Digits animate directly to the new value using CSS transitions.
  • No infinite-roll illusion; transitions go straight to the next index.
  • Transitions are smooth but not "slot machine style".
  • Ideal for standard animated counters and real-time updates.

2. Rolling Mode (rollingMode: true)

  • Digits roll upward through a sequence of 10 values to reach the next digit.
  • Designed to mimic a jackpot / slot machine animation.
  • Digits on the right change first; left digits delay proportionally.
  • After rolling, digits snap back to correct value without transition (visually seamless).
  • Ideal for flashy counters, jackpots, or game-like UIs.

Ripple Effect Explained

Digits that change closer to the right animate first. Those to the left wait slightly longer.

This creates a smooth ripple reminiscent of jackpot reels or odometers.

If a digit doesn’t change, it doesn't animate.


Performance

This package is designed to animate without triggering any React re-renders or layout thrashing. No animations are handled via JavaScript after setup. All transitions are GPU-accelerated and run purely via CSS variables.


Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

MIT