Skip to the page
TACTILE UI

Odometer vs odometer.js vs NumberFlow

Three ways to animate a number on a web page. I made the first one, so read this knowing that. I've tried to be fair, and if something here is wrong about the other two, email me and I'll fix it.

Checked 29 September 2026, against each package's source, docs and npm listing.

The short version

  • Pick NumberFlow if you want a clean, modern number transition in a React, Vue or Svelte app and don't need it to look like a machine. It's well maintained and very widely used.
  • Pick odometer.js if you already use it and it works. It hasn't had a release since 2017.
  • Pick tactile-odometer if the number should read as a physical counter: drums that carry, a housing, a lamp. It's free, MIT, with no dependencies.

What happens at 1,099 → 1,100

This is the difference that made me build mine.

  • tactile-odometer: the value is one spring, and each drum moves only while the drum to its right passes 9 to 0. The tens and hundreds carry together, in the last tenth of the units' turn, like a real odometer. How that works.
  • odometer.js: its animateSlide builds one ribbon of digits per column and slides every column over the same duration, starting together. The tens and hundreds start turning on the first frame, alongside the units.
  • NumberFlow: each digit transitions to its new value. Its docs don't describe a carry between digits.

Side by side

  • Install. tactile-odometer: npm install tactile-odometer, one ES module and one stylesheet. odometer.js: npm install odometer, a script and a theme stylesheet. NumberFlow: number-flow for plain JS, or @number-flow/react, @number-flow/vue or @number-flow/svelte.
  • Dependencies. tactile-odometer: none. odometer.js: none. NumberFlow: one small one (esm-env).
  • Last release. tactile-odometer: 1.0.0, 29 September 2026. odometer.js: 0.4.8, 5 February 2017. NumberFlow: 0.6.2, 18 July 2026.
  • Weekly downloads (21 to 27 September 2026). odometer.js: 46,188. NumberFlow: 2,233,416 for number-flow. tactile-odometer: new.
  • Reduced motion. tactile-odometer: the value changes instantly and no frame is requested. odometer.js: not handled in its source. NumberFlow: respected by default (respectMotionPreference).
  • Screen readers. tactile-odometer: the drums are hidden; the number is real text, announced once when it lands. odometer.js: nothing specific in its source. NumberFlow: described as accessible in its docs.
  • Big jumps. tactile-odometer: fast drums spin at a cap with a motion smear while slow ones roll, and all land exactly. odometer.js: each column slides through its ribbon, capped by a maximum number of values. NumberFlow: digits transition directly.
  • Look. tactile-odometer: a machined housing, four drum finishes (ink, bone, steel, brass), a fixed lamp, an optional red tenths drum. odometer.js: several CSS themes, including a car and a slot machine. NumberFlow: plain text in your own font, styled with CSS.
  • Size. tactile-odometer: 42.3 KB gzipped including its bundled font. The other two are smaller, and use your page's font.

Where mine is worse

  • It's heavier, because it ships a font so the drums look the same everywhere.
  • It's new. NumberFlow has years of use behind it.
  • It draws a physical object. If you want a number that sits in a line of text with no housing, NumberFlow fits better. Mine has a bare bezel for that, but it's still drums.

Play with it on the object page, or read the source at github.com/cipriantitire/tactile-odometer.