Categories: CSSScriptWeb Design

CountUp.js Guide: Animated Number Counter Options & Examples

CountUp.js is a JavaScript number animation library that counts from one numeric value to another.

It works well for stats sections, dashboard metrics, pricing counters, progress numbers, and scroll-triggered KPI blocks.

The package supports ESM imports, a UMD browser build, TypeScript declarations, custom formatting, callbacks, and animation plugins.

Features

  • Animates numbers from a start value to an end value.
  • Counts up and down based on the target value.
  • Formats decimals, separators, prefixes, and suffixes.
  • Substitutes custom numeral glyphs.
  • Applies smart easing to large values.
  • Starts counters when elements appear on screen.
  • Supports ESM imports and UMD browser scripts.
  • Includes TypeScript declarations.
  • Accepts animation plugins for custom rendering.
  • Cleans up observers and callbacks after teardown.

Use Cases

  • Add animated revenue, user, or download counters to landing pages.
  • Display KPI cards in admin dashboards.
  • Trigger stats animations inside long scrolling pages.
  • Animate pricing, savings, or progress numbers.
  • Format localized numeric counters with custom separators.

How To Use CountUp.js

Install with npm

npm install countup.js

Import CountUp In A Build System

import { CountUp } from 'countup.js';

// Create a counter for the element with id="monthly-revenue".
const revenueCounter = new CountUp('monthly-revenue', 48500, {
  prefix: '$',
  separator: ',',
  duration: 2.4
});

// Start the animation after CountUp validates the target element.
if (!revenueCounter.error) {
  revenueCounter.start();
} else {
  console.error(revenueCounter.error);
}

Use The UMD Browser Build

<div id="active-users">0</div>

<script src="dist/countUp.umd.js"></script>
<script>
  // The UMD build exposes CountUp on the countUp namespace.
  const usersCounter = new countUp.CountUp('active-users', 12750, {
    separator: ',',
    suffix: ' users'
  });

  // Start the counter after the instance passes validation.
  if (!usersCounter.error) {
    usersCounter.start();
  }
</script>

Use A Local ESM File

<div id="orders-counter">0</div>
<script src="./main.js" type="module"></script>
import { CountUp } from './js/countUp.min.js';

window.addEventListener('load', function() {
  // Count from 0 to the final order count.
  const ordersCounter = new CountUp('orders-counter', 3200, {
    separator: ','
  });

  // Start after the page finishes loading.
  ordersCounter.start();
});

Module scripts need a local server in many browsers. A direct file path can trigger a CORS error when the browser loads type="module" scripts from disk.

Count Down From A Custom Start Value

<div id="remaining-seats">120</div>
import { CountUp } from 'countup.js';

// Count down from 120 to 35.
const seatsCounter = new CountUp('remaining-seats', 35, {
  startVal: 120,
  duration: 1.8
});

seatsCounter.start();

Format Currency, Decimals, And Suffixes

<div id="conversion-rate">0</div>
import { CountUp } from 'countup.js';

// Show one decimal place and append a percent sign.
const rateCounter = new CountUp('conversion-rate', 18.7, {
  decimalPlaces: 1,
  decimal: '.',
  suffix: '%',
  duration: 2
});

rateCounter.start();

Start The Counter When It Appears On Screen

<section class="stats-panel">
  <span id="completed-projects">0</span>
</section>
import { CountUp } from 'countup.js';

// autoAnimate starts the counter when the target becomes visible.
const projectCounter = new CountUp('completed-projects', 860, {
  autoAnimate: true,
  autoAnimateDelay: 150,
  autoAnimateOnce: true
});

// Do not call start() when autoAnimate controls the animation.
if (projectCounter.error) {
  console.error(projectCounter.error);
}

autoAnimate uses IntersectionObserver in current releases. Older CountUp.js versions used enableScrollSpy, scrollSpyDelay, and scrollSpyOnce. Those names now exist as deprecated options.

Keep Digits Stable During Animation

.stats-panel span {
  font-variant-numeric: tabular-nums;
}

font-variant-numeric: tabular-nums helps counters look steadier in fonts that use variable-width digits.

Configuration Options

  • startVal (number): Sets the number where the animation begins. Default: 0.
  • decimalPlaces (number): Sets the number of digits after the decimal point. Default: 0.
  • duration (number): Sets the animation length in seconds. Default: 2.
  • useGrouping (boolean): Adds grouping separators to large numbers. Default: true.
  • useIndianSeparators (boolean): Uses Indian-style number grouping. Default: false.
  • useEasing (boolean): Applies easing to the counter animation. Default: true.
  • smartEasingThreshold (number): Sets the value threshold where smart easing begins. Default: 999.
  • smartEasingAmount (number): Sets the eased amount for values above the smart easing threshold. Default: 333.
  • separator (string): Sets the grouping separator character. Default: ','.
  • decimal (string): Sets the decimal character. Default: '.'.
  • easingFn (function): Sets a custom easing function.
  • formattingFn (function): Sets a custom formatter for the rendered value.
  • prefix (string): Adds text before the number. Default: ''.
  • suffix (string): Adds text after the number. Default: ''.
  • numerals (string[]): Replaces the default digits with custom numeral glyphs.
  • onCompleteCallback (function): Runs after the animation completes.
  • onStartCallback (function): Runs when the animation starts.
  • plugin (CountUpPlugin): Uses a custom renderer for alternate animation styles.
  • autoAnimate (boolean): Starts the animation when the target becomes visible. Default: false.
  • autoAnimateDelay (number): Sets the delay in milliseconds after auto animation triggers. Default: 200.
  • autoAnimateOnce (boolean): Runs auto animation only once. Default: false.
  • enableScrollSpy (boolean): Deprecated. Use autoAnimate.
  • scrollSpyDelay (number): Deprecated. Use autoAnimateDelay.
  • scrollSpyOnce (boolean): Deprecated. Use autoAnimateOnce.

API Methods

// Starts the counter animation.
salesCounter.start();

// Starts the animation and runs a callback after completion.
salesCounter.start(function() {
  console.log('Revenue counter finished.');
});

// Pauses the active animation or resumes a paused animation.
salesCounter.pauseResume();

// Resets the counter to its starting value.
salesCounter.reset();

// Updates the end value and animates to the new number.
salesCounter.update(72500);

// Cancels animation work and clears observers and callbacks.
salesCounter.onDestroy();

Events

CountUp.js does not provide a named event system. Use onStartCallback, onCompleteCallback, or the callback argument passed to start() when you need lifecycle hooks.

import { CountUp } from 'countup.js';

const signupCounter = new CountUp('signup-count', 2400, {
  // Runs when the animation starts.
  onStartCallback: function() {
    console.log('Signup counter started.');
  },

  // Runs after the animation completes.
  onCompleteCallback: function() {
    console.log('Signup counter completed.');
  }
});

signupCounter.start();

Plugin Example

CountUp.js supports custom animation plugins. A plugin provides a render() method that receives the target element and the formatted value for each frame.

import { CountUp } from 'countup.js';
import { Odometer } from 'odometer_countup';

// Use the Odometer plugin for a rolling digit effect.
const inventoryCounter = new CountUp('inventory-total', 99999, {
  plugin: new Odometer({
    duration: 2.3,
    lastDigitDelay: 0
  }),
  duration: 3
});

inventoryCounter.start();

Alternatives

FAQs

Q: What is CountUp.js used for?
A: CountUp.js animates numeric values for stats blocks, dashboards, pricing counters, and scroll-triggered KPI sections.

Q: Can CountUp.js count down?
A: Yes. Set a higher startVal and a lower end value.

Q: Does CountUp.js support TypeScript?
A: Yes. The npm package includes TypeScript declaration files.

Q: How do I start CountUp.js when the element appears on screen?
A: Set autoAnimate: true and create the instance. Do not call start() for that counter.

Q: Why does my module import fail from a local HTML file?
A: Browser module scripts often need a local server. Run the page through a local development server.

Q: What replaced enableScrollSpy?
A: Use autoAnimate. Use autoAnimateDelay and autoAnimateOnce for the matching delay and once-only behavior.

Changelog

05/08/2026

  • Rewrite the doc

v2.10.0 (06/02/2025)

  • This release modernizes the “scroll spy” mechanism to use an intersection observer instead of a window on-scroll handler. This also supports triggering animation when the target element becomes visible for other reasons like a modal opening or a parent div becoming visible, so several options have been renamed and old ones deprecated.

v2.9.0 (06/02/2025)

  • Allows getting the endVal from the target element

v2.8.1 (04/23/2025)

  • Provide package.json “exports” for compatibility with modern build systems.

v2.8.0 (08/26/2023)

  • Added onStartCallback option, useful for when scroll spy is enabled

v2.7.0 (06/29/2023)

  • update

v2.6.2 (05/01/2023)

  • bugfix

v2.6.1 (05/01/2023)

  • rebuild

v2.6.0 (03/13/2023)

  • Support animation plugins: A plugin is a class instance or object passed in options for the plugin param that implements a render method.
  • The plugin’s render method will be called on each frame to display the formatted value instead of CountUp’s.

v2.5.0 (03/01/2023)

  • Added new option, onCompleteCallback which gets called when the animation completes. You can still pass a callback to the start method, and it will override whatever is passed in the options.

v2.4.2 (01/29/2023)

  • Make it so when scroll spy is enabled, and scrollSpyOnce is false, CountUp will re-animate when scrolling up, as well as down

v2.4.1 (01/25/2023)

  • Added Indian separators option useIndianSeparators which will format a number like “1,00,000” instead of “100,000”
  • Added null check in printValue method to potentially fix react issue

v2.3.2 (07/10/2022)

  • Fixed a bug where, when using smart easing and counting down, the animation would take longer than configured. It also fixed an issue which caused 2 easing cycles to run for the same scenario.

v2.3.1 (06/29/2022)

  • Fix window check for SSR

v2.3.0 (06/28/2022)

  • Fixes an issue where, when the counter element’s parent is position: relative the scrollSpy function does not trigger when the element scrolls into the view

v2.2.0 (05/18/2022)

  • Added an option to make scroll spy triggered animations run only once

v2.1.0 (03/03/2022)

  • New scroll spy option to trigger animation when the element is scrolled into view.

v2.0.8 (07/28/2020)

  • Add “module” in package.json
  • remove TSLint
  • add ESLint

v2.0.7 (08/26/2020)

  • fixed: Value is not updated correctly when navigating quickly to value

v2.0.6 (08/08/2020)

  • allow certain options to be changed after instantiation
  • UMD module now included

v2.0.4 (06/20/2019)

  • Rewritten in Typescript

v1.9.3 (09/21/2018)

  • Update

The post CountUp.js Guide: Animated Number Counter Options & Examples appeared first on CSS Script.

rssfeeds-admin

Share
Published by
rssfeeds-admin

Recent Posts

Jodi’s Journal: The rest of the story behind Forward Sioux Falls

May 10, 2026 Imagine if the biggest, most influential businesses in this country came together…

18 minutes ago

Crimson Desert Adds Surprise Claw Machine Mini-Game and Lets Pet Dogs Attack Enemies as Part of Update 1.06.00

Crimson Desert developer Pearl Abyss has released this week’s update as promised, and it adds…

23 minutes ago

Nearly 50 Years Later, WKRP in Cincinnati Becomes a Real Radio Station

It took nearly 50 years. WKRP in Cincinnati is no longer just a TV sitcom.…

28 minutes ago

Record turnout, beautiful weather highlight Friday’s Chamber Golf Tournament at Big Creek

The Mountain Home Area Chamber of Commerce hosted its 2026 Four-Person Scramble Golf Tournament Friday…

36 minutes ago

Lead Hill man competes on Netflix reality show “Million Dollar Secret”

Growing up and spending all of his 44-years in Lead Hill and living on the…

37 minutes ago

MH Mayor Adams gives update on community center progress

Mountain Home Mayor Hillrey Adams says work is continuing at a rapid pace as the…

38 minutes ago

This website uses cookies.