Lightweight JavaScript Confetti Cannons Library - Celebration Fireworks


Celebrate form completions, game milestones, and marketing moments with canvas confetti bursts in plain HTML and JavaScript. hcg-confetti-cannons is a zero-dependency library with directional cannon origins, angle and spread control, built-in celebration presets, scoped canvas instances, and Promise-based chaining - without React, jQuery, or any other dependency.

On this page you will find live demos, installation (direct download, npm, CDN), a full options and API reference, and copy-paste examples for dual cannons, presets, and custom canvas rendering. Open the full interactive demo page for click-to-fire, custom options, and a scoped canvas demo.

What is hcg-confetti-cannons?

hcg-confetti-cannons is a vanilla JavaScript library for canvas-based confetti effects. Call confetti() to launch a burst of colorful particles from a cannon origin, control launch angle and spread, chain multiple cannons with Promise.all(), or use presets like confetti.celebrate() - without React, jQuery, or any other dependency.

hcg-confetti-cannons shape examples: star bursts, square and circle particles, and arc ring shapes firing upward from a cannon origin
Three confetti shape styles in hcg-confetti-cannons: stars, squares and circles, and arc rings, each bursting upward from a single cannon origin.

Why use hcg-confetti-cannons?

Confetti fits short celebratory moments that reward user actions without blocking the UI. Use hcg-confetti-cannons when you want lightweight visual feedback instead of heavy animation libraries or video assets.

For form saves, game achievements, onboarding milestones, and seasonal themes, a small canvas burst is often enough. Pair confetti with a toast notifications or status message so success is not communicated by animation alone.

Live Demo

Click a button for a quick sample, try dual cannons, click-to-fire, vector shapes, emojis, and custom text below, or tune every option in the playground. For scoped canvas and every demo on one page, open the interactive demo page.

Quick samples
Dual cannons

Fire two angled bursts from the bottom corners at once with Promise.all().

Click to fire

Set origin from the click position (normalized 0 to 1).

Click anywhere here to launch confetti
Star, arc, curl

Vector-style pieces: filled star, stroked arc curves, and looping curl spirals.

Emojis

emojis array or confetti.emoji() for emoji particles instead of shapes.

Custom text

texts array or confetti.text() for short text labels. Use colors to tint each word.

All options playground

Combine every option, then fire one burst with your settings.

confetti({ particleCount: 100, angle: 90, spread: 70, startVelocity: 60, decay: 0.91, gravity: 0.75, drift: 0, ticks: 300, scalar: 1, shapes: ['square', 'circle'], flat: false, origin: { x: 0.5, y: 0.7 }, });

Comparison Table

How hcg-confetti-cannons compares with popular confetti libraries.

Feature hcg-confetti-cannons canvas-confetti react-confetti
DependenciesNoneNoneRequires React
Approximate sizeOne small JS fileOne small JS fileReact component + peer deps
Framework requirementNone (script tag friendly)NoneReact only
Directional cannonsorigin, angle, spreadYesContinuous rain, not cannon-style bursts
Built-in presetscelebrate, fireworks, schoolPrideManual sequencesNo presets
Emoji particlesemojis option and confetti.emoji()YesNo
Custom text particlestexts option and confetti.text()NoNo
Vector shapesstar, arc, curl plus squares and circlesSquares and circlesRectangles only
Scoped canvasconfetti.create(canvas)confetti.create()Renders inside a React component
Reduced motionOpt in with disableForReducedMotion: trueManualManual
TypeScriptDefinitions includedCommunity typesBuilt-in types
License / costFree, MITFree, ISCFree, MIT

Choose hcg-confetti-cannons when you want a familiar canvas-confetti-style API with built-in celebration presets, emoji bursts, custom text labels, extra vector shapes, and zero dependencies in vanilla pages or React apps. Use react-confetti when you only need a continuous confetti rain inside a React tree and do not need directional cannon bursts.

Features

Everything included in the library at a glance:

  • Zero dependencies - one small JavaScript file.
  • Script tag or bundler - works with a plain script tag, CommonJS, or ESM.
  • Familiar API - confetti(options) with Promise return values.
  • Directional cannons - tune origin, angle, and spread.
  • Built-in presets - celebrate, fireworks, and schoolPride.
  • Scoped rendering - confetti.create(canvas) for element-bound bursts.
  • Immediate reset - confetti.reset() clears all active particles.
  • Reduced motion - optional skip when disableForReducedMotion: true.
  • TypeScript - definitions ship with the package.
  • React-friendly - call from handlers or bind a scoped canvas in useEffect.

Installation

Direct download

Source code and package:

Download hcg-confetti-cannons.js (full source) or hcg-confetti-cannons.min.js (minified) and include one script tag:

Full source:

HTML
<script src="hcg-confetti-cannons.js"></script>

Minified (smaller file for production):

HTML
<script src="hcg-confetti-cannons.min.js"></script>
npm

Install from npm:

Bash
npm install hcg-confetti-cannons

CommonJS (require):

JavaScript
const confetti = require("hcg-confetti-cannons");

ESM (import):

JavaScript
import confetti from "hcg-confetti-cannons";
CDN usage

Load from a CDN with one script tag - no npm or bundler required. The global confetti function is available as soon as the script finishes loading.

jsDelivr:

HTML
<!-- full source -->
<script src="https://cdn.jsdelivr.net/npm/hcg-confetti-cannons@1/hcg-confetti-cannons.js"></script>

<!-- minified -->
<script src="https://cdn.jsdelivr.net/npm/hcg-confetti-cannons@1/hcg-confetti-cannons.min.js"></script>

unpkg:

HTML
<!-- full source -->
<script src="https://unpkg.com/hcg-confetti-cannons@1/hcg-confetti-cannons.js"></script>

<!-- minified -->
<script src="https://unpkg.com/hcg-confetti-cannons@1/hcg-confetti-cannons.min.js"></script>

Replace @1 or @1.0.0 with the release you want. Use the .min.js URL for production. You can also self-host by uploading hcg-confetti-cannons.js or hcg-confetti-cannons.min.js to your own server.

Basic Usage

Install hcg-confetti-cannons, then fire a burst from your page script. origin.x and origin.y are normalized from 0 to 1 relative to the viewport (or the custom canvas when using confetti.create()).

Basic burst

Call confetti() with particleCount, spread, and origin for a single cannon from the bottom center.

JavaScript
confetti({
  particleCount: 120,
  spread: 70,
  origin: { x: 0.5, y: 0.9 },
});
Dual cannons

Fire two angled bursts from the bottom corners at once with Promise.all().

JavaScript
Promise.all([
  confetti({ angle: 60, origin: { x: 0, y: 1 }, particleCount: 80 }),
  confetti({ angle: 120, origin: { x: 1, y: 1 }, particleCount: 80 }),
]);
Click to fire

Set origin from the click position (normalized 0 to 1).

HTML
<div id="click-me" style="width:100%;height:400px;border:solid 1px #aaa;">Click me</div>
JavaScript
const element = document.getElementById("click-me");
element.addEventListener('click', (e) => {
    confetti({
        particleCount: 60,
        spread: 55,
        startVelocity: 35,
        origin: {
            x: e.clientX / window.innerWidth,
            y: e.clientY / window.innerHeight,
        },
    });
});
Reset

Clear all active particles on the default canvas immediately.

JavaScript
confetti.reset();
Presets

Built-in multi-burst sequences for common celebration effects:

JavaScript
// Center burst plus two side cannons
confetti.celebrate();

// Random-origin bursts for a few seconds
confetti.fireworks({ duration: 3000, interval: 250 });

// Two angled cannons from the bottom corners
confetti.schoolPride({ colors: ['#0057b7', '#ffd700'] });
Emoji particles

Pass an emojis array or call confetti.emoji() for emoji particles instead of shapes.

JavaScript
confetti.emoji({ particleCount: 80, spread: 70 });

confetti({
  emojis: ['🎉', '🎊', '🥳', '💫'],
  particleCount: 100,
  spread: 80,
});
Custom text

Pass a texts array or call confetti.text() for short text labels. Use colors to tint each word.

JavaScript
confetti.text({ particleCount: 80, spread: 70 });

confetti.text({
  texts: ['YAY', 'WOW', 'GO'],
  colors: ['#ff6b6b', '#ffd93d', '#6c9eff'],
  particleCount: 100,
  spread: 80,
});
Shapes

The shapes option controls particle shape: square, circle, or any mix.

JavaScript
confetti({ shapes: ['square', 'circle'], particleCount: 80 });
confetti({ shapes: ['square'], particleCount: 80 });
confetti({ shapes: ['circle'], particleCount: 80 });
Star, arc, curl

Vector-style pieces: filled star, stroked arc curves, and looping curl spirals. Mix all shapes for a party burst.

JavaScript
// star
confetti({ shapes: ['star'], particleCount: 70, spread: 90 });

// arc
confetti({ shapes: ['arc'], particleCount: 60, spread: 90 });

// curl
confetti({ shapes: ['curl'], particleCount: 60, spread: 90 });

// mixed
confetti({
  shapes: ['star', 'arc', 'curl', 'square', 'circle'],
  colors: ['#ff6b6b', '#ffd93d', '#ff8fab', '#6c9eff', '#4ecdc4'],
  particleCount: 120,
  spread: 100,
  origin: { x: 0.5, y: 0.5 },
});

Custom Canvas Instance

By default, the library creates a full-page fixed canvas overlay. To render inside a specific element, pass your own <canvas>:

HTML
<canvas id="party-canvas" width="600" height="400" style="border:solid 1px #aaa"></canvas>
JavaScript
const canvas = document.getElementById('party-canvas');
const party = confetti.create(canvas, { resize: true });

party({ particleCount: 80, spread: 80, origin: { x: 0.5, y: 0.8 } });
// party.reset();
// party.destroy();

Each instance has its own particle pool and animation loop. The default singleton is unaffected.

Using with React

Import confetti from the package and call it from event handlers. No instance setup is required for full-page bursts. For a scoped canvas, create the instance in useEffect and call destroy() when the component unmounts.

Try the live React demo on StackBlitz

Button burst
JavaScript
import confetti from "hcg-confetti-cannons";

function CelebrateButton() {
  const handleClick = () => {
    confetti({ particleCount: 120, spread: 70, origin: { x: 0.5, y: 0.9 } });
  };

  return <button type="button" onClick={handleClick}>Celebrate</button>;
}
Scoped canvas
JavaScript
import { useEffect, useRef } from "react";
import confetti from "hcg-confetti-cannons";

function PartyCanvas() {
  const canvasRef = useRef(null);
  const partyRef = useRef(null);

  useEffect(() => {
    if (!canvasRef.current) return undefined;
    partyRef.current = confetti.create(canvasRef.current, { resize: true });
    return () => {
      partyRef.current?.destroy();
      partyRef.current = null;
    };
  }, []);

  const fire = () => {
    partyRef.current?.({
      particleCount: 80,
      spread: 80,
      origin: { x: 0.5, y: 0.8 },
    });
  };

  return (
    <div>
      <canvas ref={canvasRef} width={400} height={200} />
      <button type="button" onClick={fire}>Fire in canvas</button>
    </div>
  );
}

Presets such as confetti.celebrate() and confetti.fireworks() work the same way from handlers. Each burst returns a Promise if you need to chain animations after the particles finish.

Options Reference

Pass these as the argument to confetti(options) or scoped instance calls.

OptionTypeDefaultDescription
particleCountnumber50Number of particles per burst
anglenumber90Launch angle in degrees (90=up)
spreadnumber45Spread arc in degrees
startVelocitynumber38Initial particle speed
decaynumber0.91Velocity multiplier per frame
gravitynumber0.75Downward acceleration per frame
driftnumber0Horizontal drift per frame
ticksnumber300Particle lifetime in frames
scalarnumber1Particle size multiplier
zIndexnumber100Overlay canvas z-index (default instance only)
colorsstring[]7-color paletteHex colors for shape particles, or fill color when using emojis or texts
shapessquare | circle | star | arc | curlsquare, circleParticle shapes; star is filled, arc and curl are stroked curves. Ignored when emojis is set.
emojisstring[]none (uses shapes)Emoji characters rendered as particles instead of shapes. confetti.emoji() defaults to ['🎉', '🎊', '✨', '🎈', '🥳'].
textsstring[]none (uses shapes)Short text labels rendered as particles; use with confetti.text(). Defaults to YAY, WOW, GO. Tint each word with colors.
origin{ x, y }{ 0.5, 0.5 }Normalized cannon origin
flatbooleanfalseWhen true, disables tilt and wobble
disableForReducedMotionbooleanfalseWhen true, skip animation if user prefers reduced motion

API Reference

All methods are on the default confetti export. Each burst returns a Promise that resolves when particles finish. Chain follow-up code with .then().

MethodDescription
confetti(options?)Fire a burst; returns a Promise
confetti.fire(options?)Alias for confetti()
confetti.reset()Clear all particles on the default canvas
confetti.create(canvas?, options?)Create a scoped instance bound to a canvas
confetti.celebrate(options?)Multi-cannon celebration preset
confetti.fireworks(options?)Random-origin fireworks preset; returned Promise has .stop()
confetti.schoolPride(options?)Dual corner cannon preset
confetti.emoji(options?)Emoji particle burst (default emoji set when omitted)
confetti.text(options?)Short text particle burst (default labels when omitted)
confetti.versionLibrary version string (read-only)

Scoped instances expose (options), fire(), reset(), and destroy().

Core methods

Fire bursts and run the next step in .then(). Use Promise.all() when several cannons should finish together.

JavaScript
confetti({ particleCount: 120, spread: 70, origin: { x: 0.5, y: 0.9 } })
  .then(() => confetti.fire({ particleCount: 50 }));

Promise.all([
  confetti({ angle: 60, origin: { x: 0, y: 1 }, particleCount: 80 }),
  confetti({ angle: 120, origin: { x: 1, y: 1 }, particleCount: 80 }),
]).then(() => {
  console.log('Dual cannons finished');
  console.log(confetti.version);
});

confetti.reset();
Scoped instance

Create a confetti instance for one canvas. Chain bursts with .then() and call destroy() when the element is removed.

HTML
<canvas id="canvas" width="600" height="400" style="border:solid 1px #aaa"></canvas>
JavaScript
const canvas = document.getElementById('canvas');
const party = confetti.create(canvas, { resize: true, zIndex: 100 });

party({ particleCount: 80, spread: 80, origin: { x: 0.5, y: 0.8 } })
  .then(() => party.fire({ particleCount: 40 }))
  .then(() => party.reset());

// when done with the canvas element:
// party.destroy();
Presets

Ready-made sequences. Chain presets with .then(). fireworks() returns a Promise with .stop() to end early.

JavaScript
confetti.celebrate().then(() => {
  confetti.schoolPride({ colors: ['#0057b7', '#ffd700'] });
});

const show = confetti.fireworks({ duration: 3000, interval: 250 });
show.then(() => console.log('Fireworks finished'));
// show.stop(); // end fireworks early
Emoji and text

Shortcut helpers for emoji and short text particles. Chain bursts with .then() or pass custom emojis / texts arrays.

JavaScript
confetti.emoji({ particleCount: 80, spread: 70 })
  .then(() => confetti.emoji({
    emojis: ['🎉', '🎊', '🥳', '💫'],
    particleCount: 100,
    spread: 80,
  }));

confetti.text({ particleCount: 80, spread: 70 })
  .then(() => confetti.text({
    texts: ['YAY', 'WOW', 'GO'],
    colors: ['#ff6b6b', '#ffd93d', '#6c9eff'],
    particleCount: 100,
    spread: 80,
  }));
Reduced motion

Skip drawing when the user has prefers-reduced-motion: reduce enabled. The Promise still resolves so follow-up code can run.

JavaScript
confetti({
  particleCount: 120,
  spread: 70,
  disableForReducedMotion: true,
}).then(() => {
  console.log('Burst finished or was skipped for reduced motion');
});

Accessibility

Confetti is decorative animation. By default, bursts run for all users. Set disableForReducedMotion: true on a call (or in your shared options) to skip rendering when the user has prefers-reduced-motion: reduce enabled.

Avoid relying on confetti alone to communicate success. Pair bursts with visible text feedback such as a notification or status message.

Browser Support

Works in all modern browsers that support canvas and requestAnimationFrame: Chrome, Firefox, Safari, Edge, and current mobile browsers. No polyfills required.

License

Released under the MIT License. Free for personal and commercial use. Copyright HTML Code Generator.

Frequently asked questions

Does this confetti library have any dependencies?

No. It is plain vanilla JavaScript with zero dependencies. Include hcg-confetti-cannons.js and call confetti() from your page script.

Can I fire confetti from a specific point on the page?

Yes. Pass origin with normalized x and y values between 0 and 1. For example, origin: { x: 0.5, y: 0.7 } fires from the horizontal center near the bottom of the viewport.

Does the library respect prefers-reduced-motion?

Yes. When disableForReducedMotion is true and the user has reduced motion enabled, confetti() resolves immediately without drawing particles.

Can I render confetti inside a specific element?

Yes. Use confetti.create(canvasElement, { resize: true }) to get a scoped instance that draws only on your canvas instead of the full-page overlay.

Are there built-in celebration presets?

Yes. confetti.celebrate(), confetti.fireworks(), and confetti.schoolPride() provide ready-made multi-burst sequences for common celebration effects.

Can I use hcg-confetti-cannons with React?

Yes. Import confetti and call it from event handlers for one-shot bursts. For a scoped canvas, create the instance inside useEffect and call destroy() in the cleanup function when the component unmounts. See React usage on this page.

Does confetti() return a Promise?

Yes. Each burst returns a Promise that resolves when all particles from that burst have finished animating. Use Promise.all() to wait for multiple cannons.