Spring Number Flow
Animated number transitions with spring physics for React.
Getting Started
Spring Number Flow is an animated number component for React. Digits spin into place with spring physics — overshooting slightly before settling.
Installation
Install the component from your command line.
// Terminal
npm install spring-number-flow @number-flow/react
Render a number
Pass a value and the component handles the animation. Every time the value changes, digits transition with a spring curve.
// my-component.tsx
'use client'
import { useState } from 'react'
import { SpringNumberFlow } from 'spring-number-flow'
export default function MyComponent() {
const [value, setValue] = useState(1234)
return (
<div>
<SpringNumberFlow value={value} />
<button onClick={() => setValue(value + 100)}>Add 100</button>
</div>
)
}
Formats
Pass any valid Intl.NumberFormat options via the format prop.
Currency
// currency.tsx
'use client'
import { useState } from 'react'
import { SpringNumberFlow } from 'spring-number-flow'
export default function Currency() {
const [value, setValue] = useState(4299)
return (
<div>
<SpringNumberFlow
value={value}
format={{ style: 'currency', currency: 'USD', trailingZeroDisplay: 'stripIfInteger' }}
/>
<button onClick={() => setValue(value + 500)}>Add $5</button>
</div>
)
}
Percentage
// percentage.tsx
'use client'
import { useState } from 'react'
import { SpringNumberFlow } from 'spring-number-flow'
export default function Percentage() {
const [value, setValue] = useState(0.847)
return (
<div>
<SpringNumberFlow
value={value}
format={{ style: 'percent', minimumFractionDigits: 1 }}
/>
<button onClick={() => setValue(Math.random())}>Randomize</button>
</div>
)
}
Counter
// counter.tsx
'use client'
import { useState } from 'react'
import { SpringNumberFlow } from 'spring-number-flow'
export default function Counter() {
const [value, setValue] = useState(42069)
return (
<div>
<SpringNumberFlow value={value} />
<button onClick={() => setValue(value + 1)}>Increment</button>
</div>
)
}
Other
Spring easing
The spring curve is exported as SPRING_EASING if you need it elsewhere in your app.
// easing.tsx
import { SPRING_EASING } from 'spring-number-flow'
element.animate({ transform: ['scale(0.8)', 'scale(1)'] }, {
duration: 750,
easing: SPRING_EASING,
})
Styling
The component renders as an inline element. Style it with standard CSS.
// styles.css
.price {
font-family: 'Geist Mono', monospace;
font-size: 64px;
font-weight: 500;
font-variant-numeric: tabular-nums;
}
The mask gradients at the edges of the digit slots are controlled via CSS custom properties.
| Property | Default |
|---|---|
--number-flow-mask-height | 0.25em |
--number-flow-mask-width | 0.5em |
API Reference
Props
All props from NumberFlow are supported except the timing and continuous overrides.
| Prop | Type | Default |
|---|---|---|
value | number | — |
format | Intl.NumberFormatOptions | — |
locales | Intl.LocalesArgument | — |
prefix | string | — |
suffix | string | — |
duration | number | 750 |
opacityDuration | number | 350 |
animated | boolean | true |