An animated, digit-by-digit number counter with a smooth rolling odometer effect, powered by Motion.
Made by SoraExamples
The preview includes three tabbed patterns:
| Tab | Pattern |
|---|---|
| Currency | Formatted counter with increment controls |
| Input | Native number input with a NumberFlow overlay — typing skips animation, stepper buttons animate |
| Countdown | HH:MM:SS with trend={-1} so digits roll downward |
Installation
File Structure
Usage
Scroll-triggered count-up
Enable scrollTrigger to count up from 0 the first time the element scrolls
into view — useful for landing-page stats sections:
Props
| Prop | Type | Default |
|---|---|---|
value? | number | - |
locales? | Intl.LocalesArgument | - |
format? | Intl.NumberFormatOptions | - |
prefix? | string | - |
suffix? | string | - |
trend? | number | ((prevValue: number, value: number) => number) | (prevValue, value) => Math.sign(value - prevValue) |
transition? | Transition | { duration: 0.9, ease: [0.16, 1, 0.3, 1] } |
spinTransition? | Transition | - |
respectMotionPreference? | boolean | true |
willChange? | boolean | false |
scrollTrigger? | boolean | false |
once? | boolean | true |
viewportMargin? | string | "0px 0px -10% 0px" |
onAnimationsStart? | () => void | - |
onAnimationsFinish? | () => void | - |
className? | string | - |
When to Use
Use NumberFlow for stats, KPIs, live counters, and pricing displays where a value updates over time and you want to draw attention to the change — dashboards, checkout totals, leaderboard scores, or animated metrics on a landing page.
It's not meant for large blocks of static numeric text; the animation overhead only pays off when the value actually changes at runtime.
Accessibility
The root element uses role="img" with an aria-label set to the fully formatted value (e.g. "$1,234.56"), so assistive technology always reads the current number as a single unit rather than a stream of individually-rolling digits, which are hidden from the accessibility tree via aria-hidden.
When prefers-reduced-motion: reduce is set, NumberFlow updates instantly with no animation by default (respectMotionPreference).
Credits
Inspired by Number Flow. Reimplemented for Motion and React.
The original is a framework-agnostic web component built in vanilla JS/CSS, with thin wrappers for React, Vue, and Svelte. This version is a ground-up port for the Sora registry: same core ideas — per-digit rolling faces, the continuous trend-loop, the edge mask — reimplemented with React state and Motion's motion/react (motion values, useTransform, AnimatePresence) in place of the original's custom element and CSS-driven animation.
Built by Axyl. A motion-first component registry for React.
Last updated: 7/6/2026