Join our Discord Community

React Counting Number

Animated number counters that don't suck. Spring-powered counting animations for React with in-view detection, decimal support, and TypeScript. Built for Next.js with shadcn/ui integration.

Trying to implement text animations?

Join our Discord community for help from other developers.


Ever watched a number count up from 0 to 10,000 and it takes forever? Or worse, it counts so fast it looks like a slot machine having a seizure? Yeah, most counting animations are garbage. This component actually gets the timing right with spring physics instead of linear interpolation nonsense.

Smooth number animations

Count up to any number with spring-based animations that feel natural:

Loading component...

Built with TypeScript and shadcn/ui, so it works with your existing React setup and Next.js applications. Spring animations handle the physics, in-view detection prevents wasted CPU cycles, and the whole thing runs at 60fps without re-renders in modern JavaScript frameworks.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/counting-number.json
npx shadcn@latest add https://www.shadcn.io/registry/counting-number.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/counting-number.json
bunx shadcn@latest add https://www.shadcn.io/registry/counting-number.json

Usage

import { CountingNumber } from "@/components/text/counting-number";

<CountingNumber
  number={42069}
  inView={true}
  transition={{ stiffness: 100, damping: 30 }}
/>;

Why most counting animations suck

Most developers either use setInterval with linear increments (looks robotic) or CSS transitions (can't handle dynamic values) in their React components. Neither approach feels natural because real-world motion doesn't work that way in JavaScript applications.

This React component uses Motion's spring physics with full TypeScript support. Springs naturally accelerate and decelerate, creating that satisfying "snap" when the number settles. The default stiffness (90) and damping (50) values took actual testing to get right—not just random numbers that "looked okay" in Next.js projects.

Plus, most counters start animating immediately on page load. Users never see them. This component waits until it's actually visible using Intersection Observer. Save those CPU cycles for something useful in modern JavaScript development.

Examples

Decimal numbers with custom separators

International formatting with proper decimal handling:

Loading component...

Countdown animations

Start from a high number and count down for timers or countdowns:

Loading component...

Features

  • Spring physics that actually feel natural (not linear garbage) in React applications
  • In-view detection so animations don't waste CPU before users see them
  • Decimal support with international formatting for JavaScript projects
  • Padding for consistent widths (no layout shift when counting) in Next.js
  • Complete TypeScript support with full type definitions and IntelliSense
  • 60fps performance using Motion values (no React re-renders)
  • Works seamlessly with shadcn/ui components and free open source integration

API Reference

CountingNumber

Animated number display with spring transitions.

PropTypeDefaultDescription
numbernumberrequiredTarget number to count to
fromNumbernumber0Starting number for animation
decimalPlacesnumber0Decimal places to display
decimalSeparatorstring"."Character for decimals
padStartbooleanfalseAdd leading zeros
inViewbooleanfalseOnly animate when visible
inViewMarginstring"0px"Viewport margin for trigger
inViewOncebooleantrueAnimate only once
transitionSpringOptions{ stiffness: 90, damping: 50 }Spring configuration
classNamestring-Additional CSS classes
...propsHTMLAttributes<HTMLSpanElement>-Standard span attributes

Spring Configuration

Motion spring physics for natural animations:

PropertyRangeEffect
stiffness1-1000Higher = faster animation
damping1-100Higher = less bounce
mass0.1-10Higher = more inertia

Common gotchas

Numbers jumping on mount: Always set inView={true} unless you want immediate animation in React applications. Otherwise the component animates before users scroll to it.

Decimal formatting breaks: The decimalSeparator prop only affects display, not parsing in this TypeScript component. Your number prop should always use standard JavaScript number format (period for decimals).

Layout shift during counting: Use padStart={true} or set a fixed width on the container in Next.js projects. Otherwise the element width changes as digits increase.

Animation feels sluggish: Default springs work for most React applications. For snappier animations, increase stiffness to 150-200. For smoother, reduce damping to 20-30 in JavaScript implementations.

Memory leaks with rapid updates: This React component handles cleanup automatically, but avoid changing the number prop in tight loops. Debounce your updates if needed.

Integration with other components

Works perfectly with Card components for dashboard metrics in React applications. Combine with Sliding Number for different animation styles in Next.js projects. The Rolling Text component offers an alternative slot-machine effect if you need that Vegas feel.

For complete dashboard experiences, pair with Charts to show both animated numbers and visualizations. This free open source component's animation timing matches well with Skeleton loading states, all with complete TypeScript integration.

Questions developers actually ask