React Sliding Number
React sliding number component with digit-by-digit animations. Smooth mechanical counter effects with spring physics using Motion, TypeScript, and shadcn/ui.
Powered by
Trying to implement text animations?
Join our Discord community for help from other developers.
Ever seen those number counters that change digits individually, like an old-school odometer or slot machine? Most implementations either snap instantly (jarring) or all digits move at once (chaos). This component slides each digit independently with proper timing, so 1234 → 5678 looks like a smooth mechanical counter, not a seizure.
Individual digit sliding animations
Numbers that slide smoothly from one value to another:
Built with TypeScript and shadcn/ui, using Motion for spring-powered digit animations in React applications. Each digit slides vertically through 0-9 with realistic physics, maintaining perfect alignment and timing. No layout shifts, no jarring snaps, just smooth mechanical precision.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/sliding-number.json
npx shadcn@latest add https://www.shadcn.io/registry/sliding-number.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/sliding-number.json
bunx shadcn@latest add https://www.shadcn.io/registry/sliding-number.json
Usage
import { SlidingNumber } from "@/components/text/sliding-number";
<SlidingNumber
number={42069}
inView={true}
decimalPlaces={2}
transition={{ stiffness: 100, damping: 15 }}
/>;
Why most sliding numbers suck
Most developers either animate the entire number as one unit (looks fake) or use CSS counters with steps (choppy). The worst ones don't handle different digit counts properly, so changing from 99 to 100 breaks the layout or causes weird jumps.
This React component treats each digit position as an independent roller, like a real mechanical counter. When 9 becomes 0, it slides through the complete 0-9 sequence instead of jumping. We use tabular-nums fonts so all digits have consistent width, preventing layout shifts during transitions.
The spring physics are crucial here: real mechanical counters have inertia and settle naturally. Linear transitions look robotic. These digits accelerate and decelerate like they have actual mass, creating that satisfying mechanical feel.
Examples
Decimal numbers with formatting
Currency and percentage displays with precise decimal handling:
Features
- Individual digit sliding with mechanical counter physics for React applications
- Tabular number fonts prevent layout shifts during digit changes
- Decimal support with configurable precision and separators
- In-view detection so animations trigger when users actually see them
- Complete TypeScript support with full spring configuration options
- Works seamlessly with shadcn/ui design tokens and theme colors
- Free open source component optimized for 60fps performance in Next.js
API Reference
SlidingNumber
Animated number display with individual digit sliding transitions.
Prop | Type | Default | Description |
---|---|---|---|
number | number | string | required | Number to display and animate |
inView | boolean | false | Only animate when visible |
inViewMargin | string | "0px" | Viewport margin for trigger |
inViewOnce | boolean | true | Animate only once |
padStart | boolean | false | Add leading zeros |
decimalSeparator | string | "." | Decimal point character |
decimalPlaces | number | 0 | Fixed decimal places |
transition | SpringOptions | { stiffness: 200, damping: 20 } | Spring physics config |
className | string | - | Additional CSS classes |
...props | HTMLAttributes<HTMLDivElement> | - | Standard div attributes |
Spring Physics Tuning
Fine-tune the mechanical counter feel:
Property | Range | Effect | Best For |
---|---|---|---|
stiffness | 100-300 | Animation speed | 200 for dashboards, 100 for smooth |
damping | 15-30 | Bounce/settle | 20 for realistic, 30 for quick |
mass | 0.2-1.0 | Inertia feel | 0.4 for light, 0.8 for heavy |
Common gotchas
Digits don't align properly: Make sure you're using a monospace or tabular-nums font in React applications. Variable-width fonts cause alignment issues during digit transitions.
Animation feels sluggish: Default spring settings work for most cases with TypeScript support. For snappier counters, increase stiffness to 250-300 and damping to 25-30 in JavaScript projects.
Layout shifts during changes: Use padStart={true}
for consistent width or set a fixed container width in Next.js applications. Otherwise short numbers (99) to long numbers (100) cause layout jumps.
Decimals don't format correctly: The decimalSeparator
prop only affects display in React components. Your input number should use standard JavaScript decimal format (periods), regardless of display preferences.
Performance issues with many counters: Each digit runs independent animations. Dozens of sliding numbers are fine, but hundreds might impact performance on lower-end devices.
Related text components you will also like
Counting Number
Spring-powered number counting with natural acceleration
Rolling Text
3D character rolling with realistic physics and perspective
Text Generate Effect
Progressive character generation with realistic typing timing
Splitting Text
Character, word, or line splitting with perfect timing
Shuffle
Random character shuffling with smooth settling animations
Shimmering Text
Wave-like shimmer effects that flow naturally across text
Questions developers actually ask
React Shuffle Text Effect
Advanced GSAP-powered text shuffling animation with character-level transformations, scroll triggers, and customizable reveal patterns. Perfect for dynamic reveals.
React Splitting Text
React text splitting with staggered character, word, or line reveals. Smooth animations that flow naturally using Framer Motion, TypeScript, and shadcn/ui.