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.
Powered by
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:
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:
Countdown animations
Start from a high number and count down for timers or countdowns:
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.
Prop | Type | Default | Description |
---|---|---|---|
number | number | required | Target number to count to |
fromNumber | number | 0 | Starting number for animation |
decimalPlaces | number | 0 | Decimal places to display |
decimalSeparator | string | "." | Character for decimals |
padStart | boolean | false | Add leading zeros |
inView | boolean | false | Only animate when visible |
inViewMargin | string | "0px" | Viewport margin for trigger |
inViewOnce | boolean | true | Animate only once |
transition | SpringOptions | { stiffness: 90, damping: 50 } | Spring configuration |
className | string | - | Additional CSS classes |
...props | HTMLAttributes<HTMLSpanElement> | - | Standard span attributes |
Spring Configuration
Motion spring physics for natural animations:
Property | Range | Effect |
---|---|---|
stiffness | 1-1000 | Higher = faster animation |
damping | 1-100 | Higher = less bounce |
mass | 0.1-10 | Higher = 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
React Text Animation Components
Text animation components for React and Next.js built with Framer Motion and shadcn/ui. Copy-paste typewriters, fades, slides, and advanced text effects with TypeScript support for modern web applications.
React Gradient Text
Gradient text that doesn't look like a rainbow threw up. Smooth flowing colors with optional neon effects for React. Built with Framer Motion, TypeScript, and shadcn/ui integration for Next.js applications.