Open-source project
inorganik/countUp.js avatar
inorganik/countUp.js

CountUp.js: Lightweight Number Animation Without Dependencies

Animates a numerical value by counting to it

8,162 stars1,352 forksTypeScriptMIT

At a glance

What is it?
A zero-dependency JavaScript library for animating numerical changes. Counts up or down, auto-triggers on scroll, and works in all browsers and frameworks.
Who is it for?
CountUp.js is for any team needing to animate number changes in dashboards, KPI displays, or counters. It adds no dependency bloat and works everywhere.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 93 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Smooth number animation with bidirectional counting

CountUp.js animates a number from one value to another, replacing instant updates with a smooth visual transition. According to the README, despite its name, CountUp can count in either direction, depending on the start and end values you provide. The library is dependency-free and supports all browsers, making it a no-cost addition to any project. Common uses include dashboard gauges that count from 0 to monthly revenue as the page loads, KPI cards on homepages that animate on scroll, vote or counter displays that update when new votes arrive, and statistics on about pages that count up to team milestones. Without CountUp, displaying a changing number means replacing it instantly, which the eye misses in the blink of a frame. With CountUp, the viewer watches the number tick and feels the change as it happens. The animation also serves as a loading indicator: viewers see something happening rather than staring at a static, potentially outdated number.

Configuration options for fine-grain control

According to the README, CountUp offers a large range of options for customization, making it adaptable to any visual design. Key options include startVal (number to start at, default 0), duration (animation seconds, default 2), decimalPlaces (decimal precision), useGrouping (1,000 vs 1000 formatting, default true), and useIndianSeparators (1,00,000 format, default false). You can set prefix and suffix strings (useful for currency symbols or units), custom decimal and separator characters (for localization), and substitute numerals entirely (for right-to-left languages or custom glyphs). Callbacks fire on animation start and completion, letting you trigger other changes when the number finishes animating. A formattingFn option applies custom logic to the displayed number before rendering, such as rounding, capping, or applying business rules. Smart easing is built in; the README notes that CountUp intelligently defers easing to make it visually noticeable, configurable via smartEasingThreshold (default 999) and smartEasingAmount (default 333). Numbers above the threshold smoothly ease in the final portion of the animation.

Using CountUp in your framework

CountUp.js available on npm as countup.js. According to the README, you can import as a module or include a UMD script and access CountUp as a global. The library integrates with Angular 2+, React, Svelte, Vue, WordPress, jQuery, and custom elements. Framework-specific wrappers exist: ngx-countUp for Angular, vue-countup-v2 for Vue, and gist examples for React and Svelte. For a simple HTML element, create an instance pointing to the target element ID and call start():

js
const countUp = new CountUp('targetId', 5234);
if (!countUp.error) {
  countUp.start();
} else {
  console.error(countUp.error);
}

Pass an options object as the third argument, or call start() with a callback function to override the onCompleteCallback option.

Auto-animation when scrolling into view

Set the autoAnimate option to true, and CountUp triggers the animation when the target element becomes visible on screen. According to the README, this uses IntersectionObserver, which is broadly supported in modern browsers. For older browser support, v2.9.0 and earlier use a window scroll handler via the deprecated enableScrollSpy option. The autoAnimateDelay option controls how many milliseconds pass before the animation starts (default 200 ms). Set autoAnimateOnce to true to run the animation only the first time the element becomes visible.

Plugin system for alternate animations

According to the README, the library supports plugins for alternate animation styles. Currently, the Odometer plugin is available, which makes numbers flip like a slot machine (mechanical odometer style) instead of smoothly easing. This style may fit better with retro or game-like designs. To use a plugin, install the plugin package and pass it to the plugin option when creating the CountUp instance. See the Odometer plugin documentation for specific setup instructions. The plugin system is extensible, so third-party developers can create custom animation styles for specialized uses.

Pausing, updating, and cleaning up

After starting an animation, you can pause and resume it by calling pauseResume(). Reset the animation to its starting state with reset(). Update the end value and re-animate by calling update(newValue). When you are done with the instance, call onDestroy() to cancel any running animation, disconnect observers, and clear callbacks. This prevents memory leaks in long-lived applications.

Installation and module formats

CountUp.js is published on npm as countup.js and version 2.10.1 is the latest release as of July 2026. The package exports both ESM (import) and UMD (require) formats, with types included for TypeScript support. The main entry point exports `countUp.umd.js`, the module exports `countUp.min.js`, and TypeScript definitions are available. You can include it via npm, use a CDN, or download from the GitHub repository. The library integrates with build tools like Rollup and Webpack. It is written in TypeScript and tested with Jest, so the source is maintainable and type-safe. A live demo is available at inorganik.github.io/countUp.js, and you can experiment with the library on Stackblitz for quick testing before integrating into your project.

Editorial conclusion

CountUp.js is for any team needing to animate number changes in dashboards, KPI displays, or counters. It adds no dependency bloat and works everywhere. Do not use it if you need simultaneous animations on dozens of elements, or if your numbers change faster than the animation frame rate. Verify that your framework integration (if you are using React, Vue or Angular) matches your bundle setup (ESM, UMD or CommonJS).

Frequently asked questions

What is countUp.js?

According to the README, CountUp.js is a dependency-free, lightweight JavaScript class that animates a numerical value by counting to it. It can count in either direction depending on the start and end values.

How do I use countUp.js?

Create a new CountUp instance with the target element ID and end value, then call start(). According to the README, the basic syntax is: const countUp = new CountUp('targetId', 5234); countUp.start();. You can pass an options object as the third argument to customize duration, formatting, easing and more.

Does CountUp.js work with React or Vue?

Yes. According to the README, framework-specific wrappers exist for React, Vue, Svelte and Angular. Vue has vue-countup-v2, and React and Svelte have gist examples. You can also use CountUp directly with any framework by passing a DOM element reference.

Can CountUp animate when I scroll to an element?

Yes. Set autoAnimate: true in the options, and CountUp uses IntersectionObserver to trigger the animation when the element becomes visible. The autoAnimateDelay option controls the delay before starting (default 200 ms).

Official sources

  1. inorganik/countUp.js on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/inorganik-countup-js.svg)](https://hysenlabs.com/projects/inorganik-countup-js)