react-confetti-explosion

A lightweight, CSS-only confetti explosion component for React with no canvas or particle engine required.

Library
npm
v3.0.3
253stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
28/100Needs Attention
Development Activity0
Maintenance0
Community36
Maturity56
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
66/100Good
Architecture68
Code Quality62
Innovation55
Learning Curve80

react-confetti-explosion renders a burst of confetti particles using pure CSS animations instead of a canvas-based particle system. It was built as a lighter alternative to canvas confetti libraries: no per-frame rendering loop, no physics engine, just generated keyframe animations that drive each particle’s fall, rotation, and drift.

The component exposes a small, well-documented prop surface — particle count, size, colors, force, duration, width/height of the explosion area, an optional z-index, and an onComplete callback — while leaving mount/unmount timing entirely to the consumer. By default it renders through a React Portal into document.body so the explosion always overlays the rest of the page correctly, with an opt-out for callers who want to control placement themselves.

What You Get

  • A single ConfettiExplosion component that renders nothing on the server and returns null when no browser window is present
  • Per-particle CSS keyframes generated at explosion time — rotation, x-axis drift, and y-axis fall are each randomized within tunable bounds (force, duration, size)
  • Configurable particle count, size, colors array, explosion force, fall height/width, and duration via typed props with JSDoc defaults
  • Optional React Portal rendering (portal prop) so the explosion overlays the full viewport by default, or renders inline when opted out
  • An onComplete callback fired once the animation duration elapses, so consumers can unmount the component or trigger a follow-up action
  • Full TypeScript types for props (ConfettiProps) exported alongside the default and named component export

Common Use Cases

  • Celebrating a completed checkout, signup, or onboarding step with a brief confetti burst
  • Rewarding a user action (achievement unlocked, goal met, streak completed) in a dashboard or gamified app
  • Adding a lightweight success animation to a form submission without pulling in a canvas-based particle library
  • Marking milestone events in marketing or product-tour UI where a full physics-based effect is unnecessary

Under The Hood

Architecture The library is intentionally tiny and split into three files: confetti.tsx (the public component and prop surface), styles.ts (a useStyles hook that computes per-particle CSS keyframes and returns generated class names plus a <style> string), and utils.ts (small pure math helpers — mapRange, rotate, coinFlip, range, and a table of 3D rotation transforms). The top-level ConfettiExplosion guards against non-browser environments (returns null if window/window.location is undefined) before delegating to an inner Explosion component, which measures its own container via a callback ref (getBoundingClientRect) to compute the explosion’s screen origin, then injects a <style> tag with per-particle @keyframes and renders each particle as a nested div pair (outer for position/rotation, inner ::after pseudo-element for color/shape). Rendering happens either inline or through createPortal(content, document.body) depending on the portal prop, so stacking-context issues in the caller’s own DOM don’t affect the explosion overlay.

Tech Stack The package targets React 16.8+ and React DOM as peer dependencies (no runtime dependency on React itself), is authored in TypeScript, and builds with Rollup (@rollup/plugin-node-resolve, @rollup/plugin-commonjs, @rollup/plugin-terser, rollup-plugin-typescript2, rollup-plugin-peer-deps-external) into CJS and ESM bundles plus .d.ts type declarations. Development and the local demo page use Vite, and the v3.x rewrite dropped the prior react-jss dependency in favor of hand-rolled scoped class names and raw injected CSS, removing a runtime CSS-in-JS dependency entirely.

Code Quality Tests use Vitest with @testing-library/react and @testing-library/jest-dom, covering the core explode/un-explode toggle behavior, the onComplete callback firing exactly once after the configured duration, and that a custom zIndex prop is applied to the portal-rendered screen element — a small but meaningful behavioral suite for a component this size. ESLint (flat config, typescript-eslint) and Prettier (with pretty-quick) are configured for linting and formatting, though there is no CI workflow visible in the repository to enforce these automatically on push or PR. Naming and prop typing are consistent throughout, with JSDoc comments documenting each prop’s purpose and default value directly in the ConfettiProps interface.

API Design The public API is a single component with sensible defaults for every prop, so the minimal usage is just <ConfettiExplosion /> with no required arguments — matching the README’s own “one line” pitch. Mount/unmount timing is left entirely to the consumer (a common React pattern: toggle a boolean, conditionally render), which keeps the component’s own logic simple at the cost of requiring callers to manage their own explosion lifecycle state. The onComplete callback and boolean portal escape hatch cover the two most common integration needs — knowing when to unmount, and controlling DOM placement — without expanding the prop surface further.

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

Search