A CSS transition can't interpolate the text of a number, so you need JS — requestAnimationFrame recalculating the current value and writing it into textContent every frame. Easing the progress (usually ease-out) makes it slow down as it arrives.
You can fake it in pure CSS by registering the number as a custom property with @property, but JS is still the more common implementation in practice. Always format large numbers with thousands separators.
When to use
Trigger it once, when the user arrives or when the value changes. Repeating it on every number in a list gets noisy.