jagnani73P.03
[the record]STATUS: NTU SINGAPORE — AUG 2026

react-easy-marquee

NPM · 105K+ DOWNLOADS
a zero-dependency React marquee driven entirely by CSS keyframes — my most-installed artifact
fig. 1 — this strip is react-easy-marquee, rendering itselfv1.2.4 · hover to pause
zero dependenciesCSS keyframes — no JS timerspauseOnHoveraxis: X / Yreversecustom duration105,000+ downloads
zero dependenciesCSS keyframes — no JS timerspauseOnHoveraxis: X / Yreversecustom duration105,000+ downloads
zero dependenciesCSS keyframes — no JS timerspauseOnHoveraxis: X / Yreversecustom duration105,000+ downloads
<Marquee>duration={8000}axis="X"reversepauseOnHoverbackgroundheight / width{children}
<Marquee>duration={8000}axis="X"reversepauseOnHoverbackgroundheight / width{children}
<Marquee>duration={8000}axis="X"reversepauseOnHoverbackgroundheight / width{children}

↳ no requestAnimationFrame, no scroll listeners — three offset copies and one CSS @keyframes translate

01THE PROBLEMthe ecosystem was too opinionated

Every React marquee package I tried was too opinionated, leaned on JavaScript animation timers, or barely let you customize anything.

So I built one from scratch: a fully customizable Marquee component that accepts any children — plain text, images, or arbitrary JSX — and scrolls them in a seamless loop. I designed, architected, and maintain the whole package end to end, from the CSS animation model to the prop API and the live demo site.

02THE ARCHITECTUREthree copies · one CSS keyframe

No timers, no requestAnimationFrame, no scroll listeners. The component renders three offset copies of your children and drives them with a single CSS @keyframes translate — so the loop is seamless and the whole thing stays lightweight and zero-dependency.

01

ACCEPT

any children — text, images, JSX

React

02

DUPLICATE

three offset copies: −1, 0, +1

offset spans

03

ANIMATE

one @keyframes translate, GPU-driven

CSS keyframes

04

LOOP

seamless — no JS, no scroll listeners

zero deps

STACK — React · TypeScript · CSS keyframes · Rollup · zero runtime dependencies
03THE HARD PARTperceived speed, made consistent

One non-trivial nuance most competing packages ignore entirely: perceived loop speed changes with content width — few or many children should still feel like the same speed. The rest is a deliberately small, sharp API:

01

consistent speed

the loop feels the same regardless of child count

02

zero dependencies

nothing pulled in beyond React itself

03

CSS-only motion

no timers or rAF — the browser does the work

04

a sharp prop API

duration, axis, reverse, pauseOnHover, background, h/w

04IN THE WILDplates 01–03 · npm + the demo
import Marquee from "react-easy-marquee";

<Marquee
  duration={8000}
  axis="X"
  reverse
  pauseOnHover
  height="80px"
>
  <img src="/logo-a.svg" />
  <h2>any children — text, images, JSX</h2>
</Marquee>