countup.js vs odometer
JavaScript Animation Libraries
countup.jsodometer

JavaScript Animation Libraries

JavaScript animation libraries enhance web applications by providing smooth and visually appealing animations for numerical values. These libraries are particularly useful for displaying statistics, metrics, or any data that requires a dynamic representation. They help improve user engagement and provide a better understanding of data through animated transitions, making the information more digestible and visually appealing. Countup.js and Odometer are two popular libraries that serve this purpose, each with its own unique features and use cases.

Npm Package Weekly Downloads Trend

3 Years

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
countup.js08,1721.26 MB10a month agoMIT
odometer0---9 years agoMIT

Feature Comparison: countup.js vs odometer

Animation Style

  • countup.js:

    Countup.js provides a simple counting animation that smoothly transitions from a starting number to a target number. It allows for customizable duration and easing functions, making it easy to create a visually appealing count-up effect that feels natural and engaging.

  • odometer:

    Odometer features a unique mechanical-style animation that mimics the look of an old-fashioned odometer. The numbers flip and roll in a visually striking manner, making it highly engaging for users. This style is particularly effective for displaying metrics that change frequently.

Customization

  • countup.js:

    Countup.js offers various customization options, including the ability to set the duration of the animation, specify easing functions, and format the output number (e.g., adding commas or decimal places). This flexibility allows developers to tailor the animation to fit their specific design needs.

  • odometer:

    Odometer allows for customization of its appearance through CSS. Developers can change the font, size, and color of the numbers, as well as the overall style of the odometer. However, the core animation style is fixed, focusing on the mechanical effect.

Ease of Use

  • countup.js:

    Countup.js is straightforward to implement, requiring minimal setup. It has a simple API that allows developers to initiate the counting animation with just a few lines of code, making it accessible for quick integrations into projects.

  • odometer:

    Odometer is also easy to use but may require additional setup for styling and configuration. It involves creating an HTML element for the odometer and initializing it with JavaScript, which might be slightly more complex than Countup.js.

Performance

  • countup.js:

    Countup.js is lightweight and optimized for performance, ensuring smooth animations without significant overhead. It is designed to handle multiple instances efficiently, making it suitable for applications with numerous animated numbers.

  • odometer:

    Odometer, while visually appealing, may have a slightly higher performance cost due to its more complex animations. However, it is still optimized for performance and can handle multiple instances, though care should be taken with excessive use.

Use Cases

  • countup.js:

    Countup.js is ideal for scenarios where you want to display statistics, scores, or any numerical data that needs to count up to a target value. It is commonly used in dashboards, reports, and presentations where quick numerical representation is needed.

  • odometer:

    Odometer is best suited for applications that require a more dynamic and engaging display of changing numbers, such as real-time statistics, speedometers, or any context where a mechanical effect enhances the user experience.

How to Choose: countup.js vs odometer

  • countup.js:

    Choose Countup.js if you need a lightweight library specifically designed for counting up to a target number with customizable duration and easing functions. It is ideal for simple numeric animations and offers a straightforward API for quick implementation.

  • odometer:

    Choose Odometer if you want a more visually striking representation of numbers with a mechanical odometer effect. It is suitable for applications that require a more stylized and engaging way to display changing numbers, such as dashboards or statistics.

README for countup.js

CountUp.js

CountUp.js is a dependency-free, lightweight Javascript class that animates a numerical value by counting to it.

Despite its name, CountUp can count in either direction, depending on the start and end values that you provide.

CountUp.js supports all browsers. MIT license.

Try the demo

Or tinker with CountUp in Stackblitz

Jump to:

Features

  • Auto-animate when element becomes visible. Use option autoAnimate = true.
  • Highly customizable with a large range of options, you can even substitute numerals.
  • Smart easing: CountUp intelligently defers easing to make it visually noticeable. Configurable in the options.
  • Plugins allow for alternate animations like the Odometer plugin

Odometer plugin

Usage:

Use CountUp with:

Use CountUp directly:

On npm as countup.js. You can import as a module, or include the UMD script and access CountUp as a global. See detailed instructions on including CountUp.

Params:

  • target: string | HTMLElement | HTMLInputElement - id of html element, input, svg text element, or DOM element reference where counting occurs.
  • endVal: number | null - the value you want to arrive at. Leave null to use the number in the target element.
  • options?: CountUpOptions - optional configuration object for fine-grain control

Options:

OptionTypeDefaultDescription
startValnumber0Number to start at
decimalPlacesnumber0Number of decimal places
durationnumber2Animation duration in seconds
useGroupingbooleantrueExample: 1,000 vs 1000
useIndianSeparatorsbooleanfalseExample: 1,00,000 vs 100,000
useEasingbooleantrueEase animation
smartEasingThresholdnumber999Smooth easing for large numbers above this if useEasing
smartEasingAmountnumber333Amount to be eased for numbers above threshold
separatorstring','Grouping separator
decimalstring'.'Decimal character
easingFnfunctioneaseOutExpoEasing function for animation
formattingFnfunctionCustom function to format the result
prefixstring''Text prepended to result
suffixstring''Text appended to result
numeralsstring[]Numeral glyph substitution
onCompleteCallbackfunctionCallback called when animation completes
onStartCallbackfunctionCallback called when animation starts
pluginCountUpPluginPlugin for alternate animations
autoAnimatebooleanfalseTrigger animation when target becomes visible
autoAnimateDelaynumber200Animation delay in ms after auto-animate triggers
autoAnimateOncebooleanfalseRun animation only once for auto-animate triggers
enableScrollSpyboolean(deprecated) Use autoAnimate instead
scrollSpyDelaynumber(deprecated) Use autoAnimateDelay instead
scrollSpyOnceboolean(deprecated) Use autoAnimateOnce instead

Example usage:

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

Pass options:

const countUp = new CountUp('targetId', 5234, options);

with optional complete callback:

const countUp = new CountUp('targetId', 5234, { onCompleteCallback: someMethod });

// or (passing fn to start will override options.onCompleteCallback)
countUp.start(someMethod);

// or
countUp.start(() => console.log('Complete!'));

Other methods:

Toggle pause/resume:

countUp.pauseResume();

Reset the animation:

countUp.reset();

Update the end value and animate:

countUp.update(989);

Destroy the instance (cancels animation, disconnects observers, clears callbacks):

countUp.onDestroy();

Auto animate when element becomes visible

Use the autoAnimate option to animate when the element is scrolled into view or appears on screen. When using autoAnimate, just initialize CountUp but do not call start().

const countUp = new CountUp('targetId', 989, { autoAnimate: true });

Note - Auto-animate uses IntersectionObserver which is broadly supported, but if you need to support some very old browsers, v2.9.0 and earlier use a window on-scroll handler when enableScrollSpy is set to true.


Alternate animations with plugins

Currently there's just one plugin, the Odometer Plugin.

To use a plugin, you'll need to first install the plugin package. Then you can include it and use the plugin option. See each plugin's docs for more detailed info.

const countUp = new CountUp('targetId', 5234, {
  plugin: new Odometer({ duration: 2.3, lastDigitDelay: 0 }),
  duration: 3.0
});

If you'd like to make your own plugin, see the docs below!

Tabular nums

To optimize the styling of counting number animations, you can take advantage of an OpenType feature called tabular nums which stabilizes jitteryness by using equal-width numbers.

In my experience, most OpenType fonts already use tabular nums, so this isn't needed. But it may help to add this style if they don't:

font-variant-numeric: tabular-nums;

Including CountUp

CountUp is distributed as an ES module, though a UMD module is also included, along with a separate requestAnimationFrame polyfill (see below).

For the examples below, first install CountUp:

npm i countup.js

Example with vanilla js

This is what is used in the demo. Checkout index.html and demo.js.

main.js:

import { CountUp } from './js/countUp.min.js';

window.onload = function() {
  var countUp = new CountUp('target', 2000);
  countUp.start();
}

Include in your html. Notice the type attribute:

<script src="./main.js" type="module"></script>

If you prefer not to use modules, use the nomodule script tag to include separate scripts:

<script nomodule src="js/countUp.umd.js"></script>
<script nomodule src="js/main-for-legacy.js"></script>

To run module-enabled scripts locally, you'll need a simple local server setup like this (test the demo locally by running npm run serve) because otherwise you may see a CORS error when your browser tries to load the script as a module.

For Webpack and other build systems

Import from the package, instead of the file location:

import { CountUp } from 'countup.js';

UMD module

CountUp is also wrapped as a UMD module in ./dist/countUp.umd.js and it exposes CountUp as a global variable on the window scope. To use it, include countUp.umd.js in a script tag, and invoke it like so:

var numAnim = new countUp.CountUp('myTarget', 2000);
numAnim.start()

Contributing

Before you make a pull request, please be sure to follow these instructions:

  1. Do your work on src/countUp.ts
  2. Lint: npm run lint
  3. Run tests: npm t
  4. Build and serve the demo by running npm start then check the demo to make sure it counts.

Creating Animation Plugins

CountUp supports plugins as of v2.6.0. Plugins implement their own render method to display each frame's formatted value. A class instance or object can be passed to the plugin property of CountUpOptions, and the plugin's render method will be called instead of CountUp's.

export declare interface CountUpPlugin {
  render(elem: HTMLElement, formatted: string): void;
}

An example of a plugin:

export class SomePlugin implements CountUpPlugin {
  // ...some properties here

  constructor(options: SomePluginOptions) {
    // ...setup code here if you need it
  }

  render(elem: HTMLElement, formatted: string): void {
    // render DOM here
  }
}

If you make a plugin, be sure to create a PR to add it to this README!