react-confetti

React component that renders physics-based confetti particles on an HTML canvas, with tunable gravity, wind, and colors.

Library
npm
v6.4.0
1,708 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
46 /100 Fair
Development Activity 0
Maintenance 32
Community 52
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
71 /100 Good
Architecture 78
Code Quality 62
Innovation 58
Learning Curve 85

react-confetti is a drop-in React component that draws animated confetti on an HTML <canvas> element — no external animation library, CSS keyframes, or DOM-heavy particle nodes required. It exposes a small, declarative prop surface (numberOfPieces, gravity, wind, friction, initialVelocityX/Y, colors, recycle, run) that maps directly onto the underlying physics simulation, so effects like a one-shot celebratory burst or a continuously falling shower are both simple prop combinations rather than custom animation code.

Internally it separates concerns cleanly: a Confetti engine owns the requestAnimationFrame loop and canvas context, a ParticleGenerator handles spawn timing and population maintenance via an easing tween, and individual Particle instances track their own position, velocity, and rotation. Consumers can also supply a confettiSource rect to control where particles spawn, a custom drawShape callback to replace the default square/circle/strip particles, and an onConfettiComplete callback to hook cleanup logic once the last piece falls off-canvas — which is where the “confetti without the cleanup” tagline comes from.

What You Get

  • A single <Confetti /> component with sensible defaults (200 pieces, gravity 0.1, recycling on) that works with zero configuration beyond width/height
  • Fine-grained physics props (gravity, wind, friction, initialVelocityX/Y) for tuning how confetti falls and drifts
  • A confettiSource rect to control the spawn area (e.g. burst from a button, rain from the top of the screen)
  • A drawShape escape hatch to render fully custom particle shapes (spirals, brand logos, emoji) instead of the default square/circle/strip mix
  • An onConfettiComplete callback and recycle/run props for one-shot bursts versus continuous effects, plus a canvasRef for direct canvas access
  • Full TypeScript definitions and dual ESM/CJS/UMD/IIFE builds via the exports map

Common Use Cases

  • Firing a one-time confetti burst after a successful checkout, signup, or form submission
  • Celebrating milestone events in a dashboard (goal reached, streak completed, achievement unlocked)
  • Full-screen ambient confetti rain for a themed landing page or seasonal promotion
  • Custom-shaped particle effects (logos, icons, emoji) via drawShape for branded celebration moments
  • Combining with a window-size hook (e.g. react-use’s useWindowSize) to keep the canvas sized to the viewport on resize

Under The Hood

Architecture

The library is a small three-layer pipeline: ReactConfetti (in src/ReactConfetti.tsx) is a thin React class component that owns the <canvas> ref and lifecycle hooks, delegating all animation work to a plain Confetti engine (src/Confetti.ts) instantiated in componentDidMount. Confetti owns the requestAnimationFrame loop, canvas 2D context, and an options object exposed via a getter/setter so that prop updates (componentDidUpdate) flow straight into the running simulation without remounting. It delegates particle population management to a ParticleGenerator (src/ParticleGenerator.ts), which tweens the active particle count toward numberOfPieces using an easing function and recycles or removes particles once they leave the canvas bounds. Individual Particle objects (not read in this pass beyond its role) track their own physics state. This separation means the React layer, the animation-loop/options layer, and the per-particle physics layer can each be reasoned about independently — changing how particles are drawn doesn’t touch the RAF loop, and changing the RAF/throttling logic doesn’t touch React lifecycle code.

Tech Stack

Written in TypeScript (94% of the codebase) with a single runtime dependency, tween-functions, used for the default easeInOutQuad easing curve exposed as the tweenFunction prop. React itself is a peer dependency supporting a wide range (^16.3.0 through ^19.0.0). The build is Rollup-based (rollup.config.ts with the TypeScript plugin) producing CJS, ESM, UMD, and IIFE bundles plus separate .d.cts/.d.mts type declarations, wired through package.json’s conditional exports map. Storybook (@storybook/react-vite) is used for interactive development and is deployed to GitHub Pages as the project’s demo site via a GitHub Actions workflow. Releases are fully automated with semantic-release (commit-analyzer, changelog, npm publish, GitHub release) triggered on pushes to master.

Code Quality

No automated test suite (no test files under src/) — quality is enforced instead through TypeScript’s type system and Biome (biome.json) for linting and formatting, run in CI on every pull request via a dedicated lint.yaml workflow and again before publish. The IConfettiOptions interface is thoroughly JSDoc-commented with defaults and descriptions for every prop, and prop extraction (extractCanvasProps) is written defensively to separate confetti-specific options from pass-through canvas/DOM props and refs. The absence of tests is a real gap for a physics/animation library, though the small, well-typed surface area limits the blast radius of regressions.

What Makes It Unique

Rather than wrapping a general animation or particle-system library, it implements a minimal purpose-built physics engine (position, velocity, friction, gravity, wind) specifically for confetti, keeping the runtime dependency footprint to essentially zero. The drawShape and confettiSource escape hatches let consumers fully customize particle appearance and spawn geometry without forking the library, and the getter/setter options pattern on the Confetti class allows live prop updates to a running animation loop without a full remount — a detail many simpler canvas-wrapper components get wrong.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers