{"id":26258458,"url":"https://github.com/vydimitrov/use-count-up","last_synced_at":"2025-05-16T07:04:04.117Z","repository":{"id":36053437,"uuid":"219424321","full_name":"vydimitrov/use-count-up","owner":"vydimitrov","description":"React/React Native component and hook to animate counting up or down to a number","archived":false,"fork":false,"pushed_at":"2025-04-14T14:52:32.000Z","size":1337,"stargazers_count":430,"open_issues_count":1,"forks_count":15,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-15T21:17:18.808Z","etag":null,"topics":["android","animate-counting","count-up","countup","ios","react","react-countup","react-native"],"latest_commit_sha":null,"homepage":"https://use-count-up.now.sh/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vydimitrov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-11-04T05:29:45.000Z","updated_at":"2025-05-14T17:14:45.000Z","dependencies_parsed_at":"2023-01-16T12:27:44.041Z","dependency_job_id":"4b27dfd3-353c-4a83-b7cc-c3f3042fe0e2","html_url":"https://github.com/vydimitrov/use-count-up","commit_stats":{"total_commits":203,"total_committers":5,"mean_commits":40.6,"dds":0.5862068965517242,"last_synced_commit":"cac3c7ec255a9ca4212c83dbcf9d6cf1a62120d8"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vydimitrov%2Fuse-count-up","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vydimitrov%2Fuse-count-up/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vydimitrov%2Fuse-count-up/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vydimitrov%2Fuse-count-up/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vydimitrov","download_url":"https://codeload.github.com/vydimitrov/use-count-up/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485053,"owners_count":22078767,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","animate-counting","count-up","countup","ios","react","react-countup","react-native"],"created_at":"2025-03-13T21:45:29.147Z","updated_at":"2025-05-16T07:04:04.094Z","avatar_url":"https://github.com/vydimitrov.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\r\n  \u003ch1\u003euse-count-up\u003c/h1\u003e\r\n  \u003ca href=\"https://www.npmjs.com/package/use-count-up\"\u003e\r\n    \u003cimg alt=\"NPM version\" src=\"https://img.shields.io/npm/v/use-count-up\" /\u003e\r\n  \u003c/a\u003e\r\n  \u003ca href=\"https://www.npmtrends.com/use-count-up\"\u003e\r\n    \u003cimg alt=\"Weekly downloads\" src=\"https://img.shields.io/npm/dw/use-count-up\" /\u003e\r\n  \u003c/a\u003e\r\n  \u003ca href=\"https://codecov.io/gh/vydimitrov/use-count-up\"\u003e\r\n    \u003cimg alt=\"Code Coverage\" src=\"https://img.shields.io/codecov/c/gh/vydimitrov/use-count-up\" /\u003e\r\n  \u003c/a\u003e\r\n  \u003ca href=\"https://bundlephobia.com/result?p=use-count-up@latest\"\u003e\r\n    \u003cimg alt=\"Bundle Size\" src=\"https://img.shields.io/bundlephobia/minzip/use-count-up\" /\u003e\r\n  \u003c/a\u003e\r\n\r\n  \u003cp\u003e\r\n    \u003cbr /\u003e\r\n    \u003cstrong\u003eReact/React Native component and hook to animate\u003cbr /\u003ecounting up or down to a number\u003c/strong\u003e\r\n  \u003c/p\u003e\r\n\u003c/div\u003e\r\n\r\n\u003chr /\u003e\r\n\r\n## Key features\r\n\r\n:trophy: Lighter implementation and smaller bundle size [in comparison with similar feature solutions](https://bundlephobia.com/scan-results?packages=use-count-up@latest,react-countup)  \r\n:flags: Declarative API _(no more imperative calls to `start()` and `update()`)_  \r\n\u0026nbsp;:iphone:\u0026nbsp; React Native support for iOS and Android  \r\n:deciduous_tree: Tree-shakable  \r\n\u0026nbsp;:file_cabinet: Server-side rendering (SSR) compatibility\r\n\r\n## Installation\r\n\r\n```\r\nyarn add use-count-up\r\n```\r\n\r\n## Demo\r\n\r\n\u003cimg src=\"https://user-images.githubusercontent.com/10707142/82188777-ac628e80-98ee-11ea-8a10-0469713a3bbc.gif\" width=\"300\"\u003e\r\n\r\nCheck the React demo on [CodeSandbox](https://codesandbox.io/s/aged-monad-0mrfu?fontsize=14) and React Native demo on [Expo Snack](https://snack.expo.io/@vydimitrov/use-count-up?platform=ios) to get started.\r\n\r\n## Component basic usage\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e \u003cCountUp isCounting end={1320} duration={3.2} /\u003e\r\n```\r\n\r\nThe `CountUp` component should be wrapped in a `Text` component when used in a React Native project like so:\r\n\r\n```jsx\r\nimport { Text } from 'react-native'\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e (\r\n  \u003cText\u003e\r\n    \u003cCountUp isCounting end={1320} duration={3.2} /\u003e\r\n  \u003c/Text\u003e\r\n)\r\n```\r\n\r\n## Hook basic usage\r\n\r\nThe hook accepts the same properties as the component. The usage for React and React Native is the same.\r\n\r\n```jsx\r\nimport { useCountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e {\r\n  const { value } = useCountUp({\r\n    isCounting: true,\r\n    end: 1320,\r\n    duration: 3.2,\r\n  })\r\n\r\n  return value\r\n}\r\n```\r\n\r\n## Props\r\n\r\nThe component and the hook accept the same props. They are fully interchangeable.\r\n\r\n| Prop Name              | Type               | Default      | Description                                                                                                                                                                              |\r\n| ---------------------- | ------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| **isCounting**         | boolean            | false        | Play and pause counting animation                                                                                                                                                        |\r\n| **start**              | number             | 0            | Initial value                                                                                                                                                                            |\r\n| **end**                | number             | -            | Target value                                                                                                                                                                             |\r\n| **duration**           | number             | -            | Animation duration in seconds. Defaults to 2 seconds if `end` is set                                                                                                                     |\r\n| **decimalPlaces**      | number             | -            | Number of decimal places after the decimal separator. Defaults to the max decimal places count from `start` and `end` props                                                              |\r\n| **decimalSeparator**   | string             | -            | Decimal separator character                                                                                                                                                              |\r\n| **thousandsSeparator** | string             | -            | Thousands separator character                                                                                                                                                            |\r\n| **easing**             | string \\| function | easeOutCubic | _Type: easeOutCubic \\| easeInCubic \\| linear \\| [easing func](http://www.gizma.com/easing/)_ \u003cbr\u003e Easing function to control the animation progress                                      |\r\n| **formatter**          | function           | -            | _Type: (value: number) =\u003e number \\| string \\| node_ \u003cbr\u003e A function that formats the output value. It has the highest priority so all other formatting options are ignored               |\r\n| **updateInterval**     | number             | 0            | Update interval in seconds. Determines how often the animated value will change. When set to 0 the value will update on each key frame                                                   |\r\n| **children**           | function           | -            | _Type: ({ value: number, reset: () =\u003e void }) =\u003e number \\| string \\| node_ \u003cbr\u003e CountUp component - children prop                                                                        |\r\n| **onComplete**         | function           | -            | _Type: () =\u003e void \\| {shouldRepeat: boolean, delay: number}_ \u003cbr\u003e On complete handler. Repeat animation by returning an object with `shouldRepeat` equals `true` and `delay` in seconds. |\r\n| **onUpdate**           | function           | -            | _Type: (currentValue: number \\| string \\| node) =\u003e void_ \u003cbr\u003e On value update event handler                                                                                              |\r\n\r\n## Return values\r\n\r\nThe hook returns the current count up value and reset method to reset the animation.\r\n\r\n```jsx\r\nimport { useCountUp } from 'use-count-up'\r\n\r\nconst { value, reset } = useCountUp({ isCounting: true })\r\n```\r\n\r\nThe component's children render function will receive as props the current count up value and reset method to reset the animation.\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e (\r\n  \u003cCountUp isCounting\u003e{({ value, reset }) =\u003e value}\u003c/CountUp\u003e\r\n)\r\n```\r\n\r\n## Why use `toLocaleString` with `formatter`\r\n\r\nNumber formatting varies per language group. For example, the number `3842.45` in German will be formatted as `3.842,45` whereas in British English it will be `3,842.45` (spot the different decimal and thousands separators). `Number.toLocaleString()` is a [built-in JS method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) that returns a string with a language-sensitive representation of the number. The basic implementation of the method will detect the default locale that is set up on the user's computer and will format the number accordingly. The browser support for `toLocaleString` [is incredibly good](https://caniuse.com/#search=number%20toLocaleString).\r\n\r\nIf you expect variance in the geographical/country distribution of your users, then this is a must. The simplest way to use `toLocaleString` with the Count up component or hook is to use the `formatter` prop, like so:\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e (\r\n  \u003cCountUp\r\n    isCounting\r\n    end={1320}\r\n    formatter={(value) =\u003e value.toLocaleString()}\r\n  /\u003e\r\n)\r\n```\r\n\r\n`toLocaleString` method accepts an object with [two parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat), `locale` and `options`, which allows further customization of the number value. Setting up the first parameter, `locale`, allows the use of a specific locale and fallback option. The second parameter, `options`, will let you format the value in a custom way. For example, you may choose to add a min and max number of decimal places, or set currency. Keep in mind though that the `locale` and `options` arguments are [not supported in all browsers](https://caniuse.com/#feat=mdn-javascript_builtins_number_tolocalestring_locales).\r\n\r\n## Recipes\r\n\r\n### Reset animation\r\n\r\nPass a key prop to CountUp component and change it when the animation should repeat. It can be also used when a change of `start` or `end` value should start the animation over.\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = ({ end }) =\u003e \u003cCountUp isCounting end={end} key={end} /\u003e\r\n```\r\n\r\n### Repeat animation on completion\r\n\r\nReturn from the `onComplete` handler an object with key `shouldRepeat: true`. Optionally the `delay` before repeating can be set. In the example below the animation will be repeated in 2 seconds\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst onComplete = () =\u003e {\r\n  // do your stuff here\r\n  return { shouldRepeat: true, delay: 2 }\r\n}\r\n\r\nconst MyComponent = () =\u003e (\r\n  \u003cCountUp isCounting end={4378.2} onComplete={onComplete} /\u003e\r\n)\r\n```\r\n\r\n### Count up to infinity\r\n\r\nDon't provide `end` and `duration` props. `start` prop can be set to any value\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e \u003cCountUp isCounting start={1024.4} /\u003e\r\n```\r\n\r\n### Count up/down n-seconds\r\n\r\nSet the `easing` to \"linear\" and `duration` to the seconds it should count up/down. The `updateInterval` can be set to 1, so it updates once every second. Here is an example of a 10-second count-down:\r\n\r\n```jsx\r\nimport { CountUp } from 'use-count-up'\r\n\r\nconst MyComponent = () =\u003e (\r\n  \u003cCountUp\r\n    isCounting\r\n    start={10}\r\n    end={0}\r\n    duration={10}\r\n    easing=\"linear\"\r\n    updateInterval={1}\r\n    onUpdate={(currentValue) =\u003e {\r\n      // it will fire once every second\r\n    }}\r\n  /\u003e\r\n)\r\n```\r\n\r\n## Browser support\r\n\r\nThe component and hook support [all modern browsers](https://caniuse.com/?search=es6) targeting `es6`. Internet Explorer (IE) is not longer supported.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvydimitrov%2Fuse-count-up","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvydimitrov%2Fuse-count-up","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvydimitrov%2Fuse-count-up/lists"}