react-confetti-burst
v1.0.7
Published
A high-performance, zero-dependency React confetti component with directional bursts using Canvas API
Maintainers
Readme
react-confetti-burst 🎉
A high-performance, zero-dependency React confetti component with realistic particle physics using the native Canvas API.
🎮 Live Playground | 📦 GitHub
Features
- 🚀 Zero dependencies - Pure React + Canvas API
- 🎯 Directional bursts - Up, down, left, right, radial, or custom angles
- ⚡ High performance - Optimized canvas rendering with 60fps
- 🎨 Realistic physics - Wobble, tilt, roll, and rotate effects
- 📦 Tiny bundle - Tree-shakable presets for optimal bundle size
- 🔷 TypeScript first - Full type safety built-in
- ♿ Accessible - Respects
prefers-reduced-motion
Installation
npm install react-confetti-burst
# or
yarn add react-confetti-burst
# or
pnpm add react-confetti-burstQuick Start
The Simplest Way - ConfettiButton
import { ConfettiButton } from 'react-confetti-burst';
function App() {
return (
<ConfettiButton>
Click me! 🎉
</ConfettiButton>
);
}Using the Hook - useConfetti
import { useConfetti } from 'react-confetti-burst';
function App() {
const { fire } = useConfetti();
return (
<button onClick={(e) => fire({ x: e.clientX, y: e.clientY })}>
Celebrate!
</button>
);
}Functional API - confetti()
import { confetti } from 'react-confetti-burst';
// Basic burst from center
confetti();
// With options
confetti({
particleCount: 150,
size: 4,
spread: 70,
origin: { x: 0.5, y: 0.5 }
});confetti() Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| particleCount | number | 100 | Number of confetti particles to launch |
| size | number | 4 | Base size of particles in pixels |
| angle | number | 90 | Launch angle in degrees (90 = straight up) |
| spread | number | 45 | Spread angle in degrees |
| startVelocity | number | 45 | Initial velocity in pixels per frame |
| decay | number | 0.94 | Speed decay factor (0-1) |
| gravity | number | 1 | Gravity strength (1 = full, 0 = none) |
| drift | number | 0 | Horizontal drift (-1 to 1) |
| ticks | number | 200 | Animation duration in frames |
| origin | { x, y } | { x: 0.5, y: 0.5 } | Origin position (0-1 coordinates) |
| colors | string[] | Rainbow colors | Array of hex colors |
| shapes | string[] | ['square', 'circle'] | Particle shapes |
| scalar | number | 1 | Scale multiplier for particle size |
| flat | boolean | false | Disable 3D effects (2D mode) |
| zIndex | number | 100 | Canvas z-index |
| disableForReducedMotion | boolean | false | Respect reduced motion preference |
API Reference
Components
<ConfettiButton>
A button that automatically fires confetti on click.
import { ConfettiButton } from 'react-confetti-burst';
<ConfettiButton
confettiOptions={{
particleCount: 50,
spread: 60,
colors: ['#ff6b6b', '#4ecdc4', '#ffe66d'],
}}
>
Click me!
</ConfettiButton>Props:
confettiOptions?: ConfettiBurstOptions- Configuration for the confetti burstfireOnClick?: boolean- Whether to fire on click (default:true)- All standard button HTML attributes
<ConfettiBurst>
Declarative component for conditional confetti.
import { ConfettiBurst } from 'react-confetti-burst';
<ConfettiBurst
active={showConfetti}
origin={{ x: 500, y: 300 }}
options={{ particleCount: 50 }}
onComplete={() => setShowConfetti(false)}
/>Hooks
useConfetti()
The main hook for programmatic confetti control.
import { useConfetti } from 'react-confetti-burst';
function App() {
const { fire, fireFromElement, isActive, stopAll } = useConfetti();
// Fire from a specific point
const handleClick = (e: React.MouseEvent) => {
fire({ x: e.clientX, y: e.clientY }, {
particleCount: 50,
direction: { direction: 'up', spread: 45 },
});
};
// Fire from an element's center
const buttonRef = useRef<HTMLButtonElement>(null);
const handleButtonClick = () => {
fireFromElement(buttonRef.current);
};
return (
<>
<div onClick={handleClick}>Click anywhere</div>
<button ref={buttonRef} onClick={handleButtonClick}>
Fire from me!
</button>
{isActive && <p>Animation running...</p>}
<button onClick={stopAll}>Stop All</button>
</>
);
}Returns:
fire(origin, options?)- Fire confetti from a point{ x, y }fireFromElement(element, options?)- Fire from an element's centerisActive- Boolean indicating if any animation is runningstopAll()- Stop all active animations
Functional API
confetti(options?)
Fire confetti imperatively from anywhere in your code.
import { confetti } from 'react-confetti-burst';
// Simple burst
confetti();
// Customized burst
confetti({
particleCount: 100,
spread: 70,
origin: { x: 0.5, y: 0.5 },
colors: ['#ff0000', '#00ff00', '#0000ff'],
});
// Directional burst
confetti({
particleCount: 50,
direction: {
direction: 'up',
spread: 45,
velocity: [20, 40],
},
});Configuration Options
ConfettiBurstOptions (for React components/hooks)
interface ConfettiBurstOptions {
// Number of particles (default: 100)
particleCount?: number;
// Base particle size in pixels (default: 4)
size?: number;
// Direction configuration
direction?: {
direction?: 'up' | 'down' | 'left' | 'right' | 'radial' | 'custom';
angle?: number; // For 'custom' direction (degrees)
spread?: number; // Spread angle (default: 45)
velocity?: [number, number]; // Min/max velocity
};
// Particle appearance
particle?: {
size?: [number, number]; // Min/max size
colors?: string[]; // Array of colors
shapes?: ('square' | 'circle' | 'star' | 'triangle')[];
opacity?: [number, number]; // Min/max opacity
};
// Physics
physics?: {
gravity?: number; // Gravity strength (default: 0.5)
friction?: number; // Air friction (default: 0.99)
wind?: number; // Horizontal wind force
};
// Lifecycle callbacks
onStart?: () => void;
onComplete?: () => void;
}Particle Physics
The confetti engine features realistic particle physics with four independent effects:
- Wobble - Side-to-side sway like leaves falling
- Tilt - 3D rotation creating a tumbling effect
- Roll - Flip animation with darkening on the back side
- Rotate - 2D spin around the z-axis
Set flat: true to disable all 3D effects for a simpler 2D animation.
Examples
Directional Bursts
import { useConfetti } from 'react-confetti-burst';
function DirectionalExample() {
const { fire } = useConfetti();
const fireUp = () => fire({ x: 400, y: 500 }, {
direction: { direction: 'up', spread: 30 },
});
const fireRadial = () => fire({ x: 400, y: 300 }, {
direction: { direction: 'radial' },
});
return (
<>
<button onClick={fireUp}>Fire Up ⬆️</button>
<button onClick={fireRadial}>Radial Burst 💥</button>
</>
);
}Custom Colors
<ConfettiButton
confettiOptions={{
particle: {
colors: ['#FFD700', '#FF6B6B', '#4ECDC4', '#45B7D1'],
},
}}
>
Golden Burst ✨
</ConfettiButton>Form Submission Success
import { confetti } from 'react-confetti-burst';
async function handleSubmit(data: FormData) {
const response = await submitForm(data);
if (response.success) {
confetti({
particleCount: 150,
size: 5,
spread: 70,
origin: { x: 0.5, y: 0.6 },
});
}
}Firework Effect
import { confetti } from 'react-confetti-burst';
// Built-in fireworks preset
confetti.fireworks();
// Or customize
confetti.fireworks({
particleCount: 50,
colors: ['#ff0000', '#ffff00', '#00ff00'],
});School Pride (Two-sided burst)
import { confetti } from 'react-confetti-burst';
confetti.schoolPride({
colors: ['#bb0000', '#ffffff'], // Your school colors
});Snow Effect
import { confetti } from 'react-confetti-burst';
confetti.snow({
duration: 5000, // 5 seconds
colors: ['#ffffff', '#e0e0e0'],
});Presets
16 built-in presets for quick setup:
import { getPreset, getPresetNames, confetti } from 'react-confetti-burst';
// List all available presets
console.log(getPresetNames());
// ['default', 'celebration', 'firework', 'snow', 'rain', 'sparkle',
// 'confetti', 'emoji', 'hearts', 'stars', 'money', 'pride',
// 'christmas', 'halloween', 'newYear', 'birthday']
// Use a preset with the React hook
const { fire } = useConfetti();
const preset = getPreset('celebration');
fire({ x: 500, y: 300 }, preset.options);| Preset | Description |
|--------|-------------|
| default | Balanced burst with realistic paper physics |
| celebration | Big party with lots of colorful confetti |
| firework | Firework explosion with secondary bursts |
| snow | Gentle falling snowflakes |
| rain | Rainfall effect |
| sparkle | Sparkling gold stars with glow |
| confetti | Classic continuous falling confetti |
| emoji | Emoji celebration (🎉🎊🥳✨🎈) |
| hearts | Floating hearts |
| stars | Shooting stars |
| money | Money rain (💰💵💸🤑💎) |
| pride | Rainbow pride celebration |
| christmas | Christmas themed (🎄🎅🎁❄️⭐) |
| halloween | Spooky Halloween (🎃👻🦇🕷️💀) |
| newYear | New Year fireworks |
| birthday | Birthday party (🎂🎁🎈🎉🥳) |
Custom Shapes
Create confetti with custom SVG paths, text, or emoji:
import { shapeFromPath, shapeFromText, shapesFromEmoji } from 'react-confetti-burst';
// SVG path shape
const star = shapeFromPath({
path: 'M0,-1 L0.588,0.809 L-0.951,-0.309 L0.951,-0.309 L-0.588,0.809 Z',
});
// Text/emoji shape
const heart = shapeFromText({ text: '❤️', scalar: 2 });
// Multiple emoji shapes
const partyEmoji = shapesFromEmoji(['🎉', '🎊', '✨', '🥳']);
// Use with confetti
fire({ x: 500, y: 300 }, {
particle: { shapes: [star, heart, ...partyEmoji] },
});Advanced Physics Configuration
Fine-tune particle behavior:
fire({ x: 500, y: 300 }, {
physics: {
gravity: 0.5, // Lower = floatier
drag: 0.05, // Air resistance
wind: 0.3, // Horizontal wind
windVariation: 0.1, // Wind randomness
wobble: true, // 3D wobble effect
wobbleSpeed: 2, // Wobble oscillation speed
flutter: true, // Paper-like flutter
flutterIntensity: 0.4, // Flutter strength
bounce: 0.5, // Floor bounce factor
floor: 600, // Y position of floor
},
});Performance Tips
- Keep
particleCountunder 200 for mobile devices - Use
setMaxPoolSize()to control memory usage - Shapes like
'circle'and'square'render faster than'star'or'heart' - Set
flat: trueto disable 3D effects for better performance - The library automatically caps device pixel ratio at 2x
- Particles are automatically culled when they leave the viewport
Browser Standalone (CDN)
Use without React via the IIFE browser build:
<script src="https://unpkg.com/react-confetti-burst/dist/confetti.browser.js"></script>
<script>
// Global `confetti` function is available
confetti({ particleCount: 100, spread: 70 });
</script>Or import via package exports:
import confetti from 'react-confetti-burst/browser';Migration from canvas-confetti
The confetti() function is API-compatible with canvas-confetti:
// canvas-confetti
import confetti from 'canvas-confetti';
confetti({ particleCount: 100, spread: 70 });
// react-confetti-burst (same API!)
import { confetti } from 'react-confetti-burst';
confetti({ particleCount: 100, spread: 70 });
// Additional methods
confetti.fireworks();
confetti.schoolPride({ colors: ['#bb0000', '#ffffff'] });
confetti.snow({ duration: 5000 });
confetti.burst({ x: 0.5, y: 0.3 });
confetti.reset();FAQ
Q: Does it work with SSR/Next.js?
A: Yes. All DOM access is guarded by isBrowser() checks. The library is safe to import in server environments.
Q: Why doesn't confetti appear?
A: Check if prefers-reduced-motion is enabled in your OS settings. The library respects this accessibility preference and will silently skip animations.
Q: How do I control memory usage?
A: Use setMaxPoolSize(n) to limit the particle object pool. The default is 500. Call forceCleanup() to immediately release all resources.
Q: Can I use it without React?
A: Yes! Use the browser standalone build (dist/confetti.browser.js) or the confetti() functional API which doesn't require React components.
Browser Support
- Chrome 60+
- Firefox 55+
- Safari 11+
- Edge 79+
Support
If you find this package helpful, consider buying me a coffee! ☕
License
MIT © ihakalanka
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
