React CountUp

6.5.3 · active · verified Sun Apr 19

react-countup is a React component that provides an easy-to-use wrapper around the CountUp.js library, enabling numerical value animations within React applications. As of version 6.5.3, the library is actively maintained, with frequent patch and minor releases primarily focused on dependency updates, bug fixes, and incorporating new features from the underlying countup.js library, such as `useIndianSeparators` and scroll spy enhancements. It offers both a declarative component API (<CountUp />), a flexible render prop pattern, and a `useCountUp` hook for more fine-grained imperative control over the animation instance. Key differentiators include its robust API for controlling animation duration, delay, decimal and grouping separators, prefixes/suffixes, easing functions, and scroll-triggered animations, abstracting away the direct CountUp.js instance management. It also ships with TypeScript types, enhancing developer experience in typed projects.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates the primary ways to use react-countup: as a simple component, with a render prop for manual control, and using the `useCountUp` hook for imperative animation management, including handling dynamic `end` values with the `redraw` prop.

import React, { useState } from 'react';
import { CountUp, useCountUp } from 'react-countup';

const App: React.FC = () => {
  const [dynamicValue, setDynamicValue] = useState(500);

  // Example using the useCountUp hook for imperative control
  const { countUp, start, pauseResume, reset, update } = useCountUp({
    start: 0,
    end: 100,
    delay: 1000,
    duration: 5,
    onStart: () => console.log('Hook animation started!'),
    onEnd: () => console.log('Hook animation ended!'),
  });

  return (
    <div>
      <h1>React CountUp Examples</h1>

      <h2>Simple Component:</h2>
      <CountUp
        start={0}
        end={2024}
        duration={3}
        delay={0.5}
        prefix="Year: "
        suffix="!"
        separator=","
        decimals={0}
        useEasing={true}
        onEnd={() => console.log('Component animation finished!')}
      />
      <br /><br />

      <h2>Render Prop Example:</h2>
      <CountUp start={500} end={1000} duration={2} delay={1} useGrouping={false}>
        {({ countUpRef, start: renderPropStart }) => (
          <div>
            <span ref={countUpRef} />
            <button onClick={renderPropStart}>Start Render Prop</button>
          </div>
        )}
      </CountUp>
      <br /><br />

      <h2>Hook (Imperative Control):</h2>
      <div>
        <p>Current Hook Value: {countUp}</p>
        <button onClick={start}>Start Hook</button>
        <button onClick={pauseResume}>Pause/Resume Hook</button>
        <button onClick={reset}>Reset Hook</button>
        <button onClick={() => update(Math.random() * 500 + 100)}>Update Hook</button>
      </div>
      <br /><br />

      <h2>Dynamic Value with 'redraw' prop:</h2>
      <button onClick={() => setDynamicValue(Math.floor(Math.random() * 1000))}>
        Change Value to: {dynamicValue}
      </button>
      <br />
      <CountUp
        start={0}
        end={dynamicValue}
        duration={2}
        redraw={true}
        className="dynamic-counter"
      />
    </div>
  );
};

export default App;

view raw JSON →