{"id":11675,"library":"react-countup","title":"React CountUp","description":"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.","status":"active","version":"6.5.3","language":"javascript","source_language":"en","source_url":"https://github.com/glennreyes/react-countup","tags":["javascript","react-component","react","react.js","countup","countup.js","counter","animation","typescript"],"install":[{"cmd":"npm install react-countup","lang":"bash","label":"npm"},{"cmd":"yarn add react-countup","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-countup","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for React applications.","package":"react","optional":false},{"reason":"Core animation engine that react-countup wraps.","package":"countup.js","optional":false}],"imports":[{"note":"CountUp is a named export, not a default export.","wrong":"import CountUp from 'react-countup'","symbol":"CountUp","correct":"import { CountUp } from 'react-countup'"},{"note":"The `useCountUp` hook is a named export for functional components and custom hooks, incompatible with CommonJS `require` for direct access to the hook as a function.","wrong":"const useCountUp = require('react-countup').useCountUp","symbol":"useCountUp","correct":"import { useCountUp } from 'react-countup'"},{"note":"Importing types for TypeScript usage to ensure correct prop definitions.","symbol":"CountUpProps","correct":"import type { CountUpProps } from 'react-countup'"}],"quickstart":{"code":"import React, { useState } from 'react';\nimport { CountUp, useCountUp } from 'react-countup';\n\nconst App: React.FC = () => {\n  const [dynamicValue, setDynamicValue] = useState(500);\n\n  // Example using the useCountUp hook for imperative control\n  const { countUp, start, pauseResume, reset, update } = useCountUp({\n    start: 0,\n    end: 100,\n    delay: 1000,\n    duration: 5,\n    onStart: () => console.log('Hook animation started!'),\n    onEnd: () => console.log('Hook animation ended!'),\n  });\n\n  return (\n    <div>\n      <h1>React CountUp Examples</h1>\n\n      <h2>Simple Component:</h2>\n      <CountUp\n        start={0}\n        end={2024}\n        duration={3}\n        delay={0.5}\n        prefix=\"Year: \"\n        suffix=\"!\"\n        separator=\",\"\n        decimals={0}\n        useEasing={true}\n        onEnd={() => console.log('Component animation finished!')}\n      />\n      <br /><br />\n\n      <h2>Render Prop Example:</h2>\n      <CountUp start={500} end={1000} duration={2} delay={1} useGrouping={false}>\n        {({ countUpRef, start: renderPropStart }) => (\n          <div>\n            <span ref={countUpRef} />\n            <button onClick={renderPropStart}>Start Render Prop</button>\n          </div>\n        )}\n      </CountUp>\n      <br /><br />\n\n      <h2>Hook (Imperative Control):</h2>\n      <div>\n        <p>Current Hook Value: {countUp}</p>\n        <button onClick={start}>Start Hook</button>\n        <button onClick={pauseResume}>Pause/Resume Hook</button>\n        <button onClick={reset}>Reset Hook</button>\n        <button onClick={() => update(Math.random() * 500 + 100)}>Update Hook</button>\n      </div>\n      <br /><br />\n\n      <h2>Dynamic Value with 'redraw' prop:</h2>\n      <button onClick={() => setDynamicValue(Math.floor(Math.random() * 1000))}>\n        Change Value to: {dynamicValue}\n      </button>\n      <br />\n      <CountUp\n        start={0}\n        end={dynamicValue}\n        duration={2}\n        redraw={true}\n        className=\"dynamic-counter\"\n      />\n    </div>\n  );\n};\n\nexport default App;","lang":"typescript","description":"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."},"warnings":[{"fix":"Review the GitHub release notes and README for your target major version to identify necessary code adjustments.","message":"Major version updates (v3, v4, v5, v6) typically introduce breaking changes in API, prop names, or component behavior. Always consult the specific version's release notes and migration guides on GitHub when upgrading across major versions.","severity":"breaking","affected_versions":">=3.0"},{"fix":"Add the `redraw={true}` prop to your `CountUp` component if you intend for the animation to restart upon changes to its `end` prop.","message":"The `redraw` prop is essential for re-triggering the animation when the `end` value changes. If `redraw` is not set to `true`, the CountUp component will only display the new `end` value without animating from the previous value.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"If experiencing ESM import issues, verify your build system's module resolution and consider testing updates in a controlled environment to catch unexpected behaviors.","message":"The `v6.5.3` release note 'Exclude esm build' is ambiguous. While likely a fix for bundling, it could subtly alter ESM module resolution or availability, potentially affecting specific build toolchains or module loaders. If you encounter issues with ESM imports after updating, investigate your build configuration.","severity":"gotcha","affected_versions":">=6.5.3"},{"fix":"For SSR applications, consider dynamically importing the `CountUp` component or rendering it only on the client-side (e.g., using `typeof window !== 'undefined'` checks or a dedicated `NoSSR` component) to avoid issues.","message":"When using react-countup in Server-Side Rendering (SSR) environments, you might encounter issues due to its reliance on browser-specific APIs for animation. While v6.3.2 included fixes for SSR conditions, careful implementation is still required.","severity":"gotcha","affected_versions":">=1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `useCountUp` is called directly within the body of a React function component or another custom hook, strictly adhering to React's Rules of Hooks.","cause":"Attempting to use the `useCountUp` hook outside of a React function component or a custom hook.","error":"Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component."},{"fix":"Interact with the CountUp instance methods (e.g., `start`, `pauseResume`) only when the component is mounted and the ref is available, often within React's `useEffect` hook or event handlers that trigger after initial render.","cause":"This error typically occurs when attempting to access the `countUpRef` or other imperative methods from the render prop API before the component has fully mounted or when the ref is not yet assigned.","error":"TypeError: Cannot read properties of undefined (reading 'current') / Cannot access 'countUpRef' before initialization"},{"fix":"To make the animation restart when the `end` prop changes, you must explicitly add the `redraw` prop to the `CountUp` component: `<CountUp end={newValue} redraw />`.","cause":"By default, the `CountUp` component does not re-animate if the `end` prop changes after its initial render; it simply updates the displayed value without animation.","error":"CountUp animation does not restart when the numeric 'end' prop changes."}],"ecosystem":"npm"}