Skip to content

Rule · Lint

new Intl.NumberFormat / Intl.NumberFormat( / new Color( inside an animation-frame callback

lint/allocation-per-framewarnvoid lintupdated

Why it matters

Number tickers (Magic UI NumberTicker, React Bits CountUp) build a formatter on every frame of a spring; WebGL backgrounds (React Bits Aurora) allocate colours per frame. Formatter construction costs ~50–100× a format() call and the garbage causes GC pauses mid-animation.

How to fix it

Create formatters and colour objects once (module scope or useMemo) and only call .format() / mutate inside requestAnimationFrame, useAnimationFrame, .on('change') or useMotionValueEvent callbacks.

Example

tsx
const fmt = useMemo(() => new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }), [locale]);
useMotionValueEvent(spring, 'change', (v) => { if (ref.current) ref.current.textContent = fmt.format(v); });

void lint reports 67 rules in this category. Static source checks with no browser: Tailwind v4 silent failures, Next.js 16 API traps, React render-body bugs, accessibility markup, SEO files and motion hygiene.