Join our Discord Community

React Sliding Number

Numbers that slide like a slot machine, but actually readable. Smooth digit-by-digit animations with spring physics that don't make your dashboard look like Vegas. Built with Motion, TypeScript, and shadcn/ui.

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:

Loading component...

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:

Loading component...

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.

PropTypeDefaultDescription
numbernumber | stringrequiredNumber to display and animate
inViewbooleanfalseOnly animate when visible
inViewMarginstring"0px"Viewport margin for trigger
inViewOncebooleantrueAnimate only once
padStartbooleanfalseAdd leading zeros
decimalSeparatorstring"."Decimal point character
decimalPlacesnumber0Fixed decimal places
transitionSpringOptions{ stiffness: 200, damping: 20 }Spring physics config
classNamestring-Additional CSS classes
...propsHTMLAttributes<HTMLDivElement>-Standard div attributes

Spring Physics Tuning

Fine-tune the mechanical counter feel:

PropertyRangeEffectBest For
stiffness100-300Animation speed200 for dashboards, 100 for smooth
damping15-30Bounce/settle20 for realistic, 30 for quick
mass0.2-1.0Inertia feel0.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.

Integration with other components

Perfect for dashboard Card components showing metrics and KPIs in React applications. Combines well with Progress for completion percentages or Badge for status counts in Next.js projects.

For complete analytics experiences, pair with Charts to show both visual and numerical data. This free open source component works great with Skeleton loading states and Table components for data displays, all with complete TypeScript integration.

Questions developers actually ask