react-confetti-explosion
A lightweight, CSS-only confetti explosion component for React with no canvas or particle engine required.
Repository Health
Technical Analysis
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
ConfettiExplosioncomponent 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 (
portalprop) so the explosion overlays the full viewport by default, or renders inline when opted out - An
onCompletecallback 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.
Used by 2 apps in this directory
AnythingLLM
Developer Tools · Automation · AI Assistants
The all-in-one AI platform for private document chat, no-code agents, and local LLMs with zero setup friction.
Dokploy
Devops · Hosting Control Panel · Security
Self-hosted PaaS that deploys apps and databases on your own VPS using Docker, Traefik, and multi-build-system orchestration