npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-confetti-shooter

v1.2.3

Published

A simple, one-line React confetti library with directional shooting

Readme

React Confetti Shooter 🎉

A simple, lightweight React hook for creating confetti animations with directional shooting and intelligent auto-triggering. Perfect for celebrations, notifications, and interactive experiences.

✨ Features

  • 🎯 Directional shooting: Left, right, top, or center burst patterns
  • 📍 Source positioning: Confetti originates from any element position
  • Auto-trigger: Automatic confetti on component mount with smart controls
  • 🔄 Loop mode: Continuous confetti celebrations with customizable intervals
  • 🎨 Customizable: Particle count, colors, timing, and physics
  • 💡 One-line usage: Just call triggerConfetti('direction')
  • 📱 Responsive: Works on all screen sizes
  • 🔧 TypeScript: Full type safety included
  • 🪶 Lightweight: Zero dependencies (except React)

🚀 Installation

npm install react-confetti-shooter

Or with bun:

bun add react-confetti-shooter

📖 Quick Start

Basic Manual Trigger

import React from 'react';
import { useConfetti } from 'react-confetti-shooter';

function MyComponent() {
  const { triggerConfetti, ConfettiRenderer } = useConfetti();

  return (
    <div>
      <ConfettiRenderer />
      
      <button onClick={() => triggerConfetti('center')}>
        Celebrate! 🎉
      </button>
    </div>
  );
}

Auto-Trigger Once (Welcome Screen)

import React from 'react';
import { useConfetti } from 'react-confetti-shooter';

function WelcomeComponent() {
  const { ConfettiRenderer } = useConfetti({
    autoTrigger: {
      enabled: true,
      direction: 'center',
      count: 100,
      delay: 1000 // Triggers once after 1 second
    }
  });

  return (
    <div>
      <ConfettiRenderer />
      <h1>Welcome! 🎉</h1>
    </div>
  );
}

Loop Mode (Party Time!)

import React from 'react';
import { useConfetti } from 'react-confetti-shooter';

function PartyComponent() {
  const { ConfettiRenderer } = useConfetti({
    autoTrigger: {
      enabled: true,
      direction: 'center',
      count: 75,
      delay: 500,
      loop: true,        // Enable continuous mode
      interval: 3000     // Trigger every 3 seconds
    }
  });

  return (
    <div>
      <ConfettiRenderer />
      <h1>🎊 Party Mode Activated! 🎊</h1>
    </div>
  );
}

🔧 API Reference

useConfetti(options?)

Hook that manages confetti animations with intelligent auto-triggering.

Parameters:

  • options: UseConfettiOptions (optional) - Configuration options

Options:

  • autoTrigger: AutoTriggerOptions (optional) - Auto-trigger configuration
    • enabled: boolean - Whether to auto-trigger confetti
    • direction: Direction (optional, default: 'center') - Direction to shoot
    • count: number (optional, default: 50) - Number of particles
    • delay: number (optional, default: 0) - Initial delay in milliseconds
    • loop: boolean (optional, default: false) - Enable continuous triggering
    • interval: number (optional, default: 3000) - Time between loops (ms)

Returns:

triggerConfetti(direction, count?, sourceX?, sourceY?)

Manually triggers a confetti burst.

Parameters:

  • direction: 'left' | 'right' | 'top' | 'center' - Direction to shoot confetti
  • count: number (optional, default: 50) - Number of particles to create
  • sourceX: number (optional, default: center X) - X coordinate of confetti source
  • sourceY: number (optional, default: center Y) - Y coordinate of confetti source

ConfettiRenderer

React component that renders the confetti particles. Must be included in your JSX.

isAnimating

Boolean indicating if confetti animation is currently running.

particleCount

Number of active confetti particles currently on screen.

⚡ Auto-Trigger Modes

🎯 Once Mode (Default)

Perfect for welcome screens, success notifications, and one-time celebrations.

// Triggers once when component mounts
const { ConfettiRenderer } = useConfetti({
  autoTrigger: {
    enabled: true,
    direction: 'center',
    count: 100,
    delay: 1500 // Wait 1.5 seconds
  }
});

Behavior:

  • Triggers confetti once after the specified delay
  • Will not trigger again unless the component is remounted
  • Perfect for: Welcome screens, achievement unlocks, form submissions

🔄 Loop Mode

Great for party modes, celebration pages, and ongoing festivities.

// Continuous confetti every few seconds
const { ConfettiRenderer } = useConfetti({
  autoTrigger: {
    enabled: true,
    direction: 'center',
    count: 50,
    delay: 1000,      // Initial delay
    loop: true,       // Enable looping
    interval: 4000    // Repeat every 4 seconds
  }
});

Behavior:

  • Initial trigger after delay milliseconds
  • Continues triggering every interval milliseconds
  • Stops when enabled is set to false or component unmounts
  • Perfect for: Party modes, celebration pages, background ambiance

🎨 Direction Examples

Left Shooter

const { triggerConfetti, ConfettiRenderer } = useConfetti();

<button onClick={() => triggerConfetti('left', 60)}>
  Shoot Left ← 
</button>

Right Shooter

<button onClick={() => triggerConfetti('right', 60)}>
  Shoot Right →
</button>

Top Shooter

<button onClick={() => triggerConfetti('top', 80)}>
  Shoot Up ↑
</button>

Center Explosion

<button onClick={() => triggerConfetti('center', 100)}>
  Explode 💥
</button>

🎯 Advanced Usage

Position-Based Shooting

function InteractiveConfetti() {
  const { triggerConfetti, ConfettiRenderer } = useConfetti();

  const handleButtonClick = (
    direction: Direction,
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    const rect = event.currentTarget.getBoundingClientRect();
    const sourceX = rect.left + rect.width / 2;
    const sourceY = rect.top + rect.height / 2;
    
    triggerConfetti(direction, 50, sourceX, sourceY);
  };

  return (
    <div className="grid grid-cols-2 gap-4">
      <ConfettiRenderer />
      
      {(['left', 'right', 'top', 'center'] as const).map(direction => (
        <button
          key={direction}
          onClick={(e) => handleButtonClick(direction, e)}
          className="p-4 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
        >
          {direction.charAt(0).toUpperCase() + direction.slice(1)}
        </button>
      ))}
    </div>
  );
}

Dynamic Auto-Trigger Control

function DynamicConfetti() {
  const [isPartyMode, setIsPartyMode] = useState(false);
  
  const { ConfettiRenderer, isAnimating } = useConfetti({
    autoTrigger: {
      enabled: isPartyMode,
      direction: 'center',
      count: 60,
      delay: 500,
      loop: true,
      interval: 2500
    }
  });

  return (
    <div>
      <ConfettiRenderer />
      
      <button 
        onClick={() => setIsPartyMode(!isPartyMode)}
        className={`px-6 py-3 rounded-lg text-white font-semibold ${
          isPartyMode ? 'bg-red-500' : 'bg-green-500'
        }`}
      >
        {isPartyMode ? '⏹️ Stop Party' : '🎉 Start Party Mode'}
      </button>
      
      <p className="mt-4">
        Status: {isPartyMode ? '🎊 Party Active' : '😴 Party Stopped'}
        {isAnimating && ' | ✨ Animating'}
      </p>
    </div>
  );
}

Multi-Stage Celebration

function MultiStageCelebration() {
  const [stage, setStage] = useState(0);
  
  const stages = [
    { direction: 'left', count: 30, delay: 500 },
    { direction: 'right', count: 30, delay: 1000 },
    { direction: 'center', count: 100, delay: 1500 }
  ];
  
  const { ConfettiRenderer } = useConfetti({
    autoTrigger: stage < stages.length ? {
      enabled: true,
      ...stages[stage]
    } : { enabled: false }
  });

  useEffect(() => {
    if (stage < stages.length - 1) {
      const timer = setTimeout(() => setStage(s => s + 1), 2000);
      return () => clearTimeout(timer);
    }
  }, [stage]);

  return (
    <div>
      <ConfettiRenderer />
      <div className="text-center p-8">
        <h2>🎊 Epic Celebration Sequence! 🎊</h2>
        <p>Stage {stage + 1} of {stages.length}</p>
        <button 
          onClick={() => setStage(0)}
          className="mt-4 px-4 py-2 bg-purple-500 text-white rounded"
        >
          🔄 Restart Sequence
        </button>
      </div>
    </div>
  );
}

🎨 Styling & Customization

Built-in Colors

The library includes vibrant, celebration-ready colors:

  • #ff6b6b (Coral Red)
  • #4ecdc4 (Turquoise)
  • #45b7d1 (Sky Blue)
  • #ffd93d (Sunshine Yellow)
  • #ff8c42 (Orange Burst)
  • #a8e6cf (Mint Green)
  • #ff6f91 (Bubblegum Pink)

Animation Properties

  • Physics: Realistic gravity and motion
  • Rotation: Particles rotate as they fall
  • Cleanup: Automatic removal when off-screen
  • Performance: Optimized with requestAnimationFrame

📚 Complete Examples

Success Page with Auto-Celebration

function SuccessPage() {
  const { ConfettiRenderer } = useConfetti({
    autoTrigger: {
      enabled: true,
      direction: 'center',
      count: 150,
      delay: 800
    }
  });
  
  return (
    <div className="min-h-screen flex items-center justify-center bg-green-50">
      <ConfettiRenderer />
      
      <div className="text-center p-8 bg-white rounded-xl shadow-lg">
        <div className="text-6xl mb-4">🎉</div>
        <h1 className="text-3xl font-bold text-green-600 mb-2">Success!</h1>
        <p className="text-gray-600">Your payment has been processed.</p>
      </div>
    </div>
  );
}

Interactive Celebration Dashboard

function CelebrationDashboard() {
  const { triggerConfetti, ConfettiRenderer, particleCount, isAnimating } = useConfetti();
  const [autoMode, setAutoMode] = useState(false);
  
  const { ConfettiRenderer: AutoRenderer } = useConfetti({
    autoTrigger: {
      enabled: autoMode,
      direction: 'center',
      count: 40,
      loop: true,
      interval: 3000
    }
  });

  return (
    <div className="p-6 max-w-4xl mx-auto">
      <ConfettiRenderer />
      <AutoRenderer />
      
      <h1 className="text-4xl font-bold text-center mb-8">
        🎊 Confetti Control Center 🎊
      </h1>
      
      {/* Manual Controls */}
      <div className="bg-white rounded-lg p-6 shadow-md mb-6">
        <h2 className="text-xl font-semibold mb-4">Manual Triggers</h2>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
          {(['left', 'right', 'top', 'center'] as const).map(direction => (
            <button
              key={direction}
              onClick={() => triggerConfetti(direction, 60)}
              className="py-3 px-4 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
              disabled={isAnimating}
            >
              {direction.charAt(0).toUpperCase() + direction.slice(1)}
            </button>
          ))}
        </div>
      </div>
      
      {/* Auto Mode */}
      <div className="bg-white rounded-lg p-6 shadow-md mb-6">
        <h2 className="text-xl font-semibold mb-4">Auto Mode</h2>
        <button
          onClick={() => setAutoMode(!autoMode)}
          className={`px-6 py-3 rounded-lg text-white font-semibold transition-colors ${
            autoMode ? 'bg-red-500 hover:bg-red-600' : 'bg-green-500 hover:bg-green-600'
          }`}
        >
          {autoMode ? '⏹️ Stop Auto Mode' : '🔄 Start Auto Mode'}
        </button>
      </div>
      
      {/* Status */}
      <div className="bg-gray-100 rounded-lg p-4">
        <h3 className="font-semibold mb-2">Status</h3>
        <div className="grid grid-cols-2 gap-4 text-sm">
          <div>Active Particles: <span className="font-mono">{particleCount}</span></div>
          <div>Animation: <span className={`font-mono ${isAnimating ? 'text-green-600' : 'text-gray-500'}`}>
            {isAnimating ? 'Running' : 'Idle'}
          </span></div>
          <div>Auto Mode: <span className={`font-mono ${autoMode ? 'text-blue-600' : 'text-gray-500'}`}>
            {autoMode ? 'Enabled' : 'Disabled'}
          </span></div>
        </div>
      </div>
    </div>
  );
}

🔄 TypeScript Support

Full TypeScript support with comprehensive type definitions:

import { 
  useConfetti, 
  Direction, 
  UseConfettiOptions, 
  AutoTriggerOptions 
} from 'react-confetti-shooter';

// Type-safe direction
const direction: Direction = 'center';

// Fully typed options
const options: UseConfettiOptions = {
  autoTrigger: {
    enabled: true,
    direction: 'center',
    count: 50,
    delay: 1000,
    loop: true,
    interval: 3000
  }
};

// Type-safe hook usage
const { triggerConfetti, ConfettiRenderer, isAnimating, particleCount } = useConfetti(options);

📱 Performance & Compatibility

Browser Support

  • ✅ Chrome/Edge 60+
  • ✅ Firefox 55+
  • ✅ Safari 12+
  • ✅ Mobile browsers

Performance Features

  • Automatic particle cleanup when off-screen
  • Efficient requestAnimationFrame animations
  • Memory leak prevention with proper cleanup
  • Lightweight bundle size

Responsive Design

  • Adapts to all screen sizes
  • Viewport-relative positioning
  • Touch-friendly interactions

🛠️ Development

# Clone and setup
git clone https://github.com/LynchzDEV/lynchz-confetti.git
cd lynchz-confetti
bun install

# Build
bun run build

# Development
bun run dev

# Test locally
open test-example.html
open test-loop-example.html

🤝 Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

MIT License - see the LICENSE file for details.

🙏 Acknowledgments

Built with ❤️ for the React community. Perfect for adding joy, celebration, and interactive delight to your applications!


Ready to make your users smile? Let's shoot some confetti! 🎊✨