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 🙏

© 2026 – Pkg Stats / Ryan Hefner

grand-fireworks-js

v1.6.5

Published

Photorealistic WebGL 2 fireworks engine with 15 shell types, multi-line text effects, adaptive performance, Canvas fallback, and a choreographed Super Grand Finale. Zero dependencies.

Readme

GrandFireworks

Created by Travis MacDonald on July 15, 2026.
Version 1.6.5 · Creator website · GitHub repository

Version 1.6.5

This release adds the cinematic style, ballistic rocket arcs, persistent trail switching, smooth automatic intensity movement, style-and-colour automation, richer procedural boom profiles, mixed-style weighting, better text controls, and a stable CDN build filename. See CHANGELOG.md for the complete release notes.

Photorealistic WebGL-first fireworks with persistent long-exposure trails, HDR-style bloom, star cores, rocket exhaust, explosion flashes, secondary crackles, specialized shell geometry, grouped salvos, and a Canvas 2D fallback. The class also includes graceful stopping, an optional finale, fullscreen or contained placement, timed shows, performance presets, and synchronized multi-line hybrid text fireworks.

Open index.html for complete documentation and links to working examples.

Install

npm install grand-fireworks-js

For a no-build webpage, use the stable CDN filename:

<script src="https://cdn.jsdelivr.net/gh/travisjmac/grand-fireworks-js@main/dist/GrandFireworks.min.js"></script>

Live documentation and examples

After GitHub Pages is enabled for the repository, the complete interactive documentation will be available at:

Open the Grand Fireworks JS live documentation

View the source repository · Download the latest source ZIP

  • Moonlit Horizon — the cinematic parallax showcase.
  • Feature Demo — the shared draggable studio opened directly in feature-testing mode.
  • Config Workbench — the same studio opened with build, preview, save, load, and copy controls.
  • Fireworks Command — a tactical Mars defence game showing the engine in an arcade setting.
  • Starlight Intercept — a space-action showcase with ember fields, ship combat, and a warp ending.

The same files can be browsed directly inside the repository through the relative links in index.html, but GitHub Pages is required to run the interactive JavaScript examples as a website.

<script src="GrandFireworks.js"></script>
<script>
  const fireworks = new GrandFireworks();
  fireworks.start();
</script>

duration: 0 runs indefinitely. stop() is graceful by default: it stops new launches, finishes active fireworks, optionally plays the configured finale, then fades out.

The library exposes start, stop, pause, resume, clear, destroy, launch, launchText, launchTextSequence, cancelTextSequence, launchFinale, launchWorldEnder, finalize, setOptions, setOpacity, setZoom, setStyle, setColorTheme, feelingLucky, getOptions, and getStats.

Use setStyle('cinematic') for a restrained, realistic show with warm pyrotechnic colours, longer ember trails, softer bloom, slower launches, and fewer simultaneous shells.

launch(), launchText(), and launchFinale() are standalone-safe: they wake the renderer when the regular show is idle, stopped, paused, or fading, play only the requested effect, then fade away automatically. They do not restart automatic launches.

The Super Grand Finale launches one central carrier, bursts it into independently glowing comet trails, sends those trails in different radial directions, and then detonates each into a large ringed, crackling secondary shell. Configure it with finale.trails, finale.trailFlight, finale.burstScale, finale.maxWaitBeforeLaunch, finale.particleScale, finale.finishDelay, and finale.maxDuration.

launchWorldEnder() reuses that same carrier-and-trail pipeline, then turns each first-wave burst into mixed warheads. Configure worldEnder.firstSplitCount, worldEnder.secondSplitCount, worldEnder.promotionChance, worldEnder.maxChainDepth, and worldEnder.recursionDurationMs to balance spectacle against performance.

Launch text messages one at a time with a cancellable sequence:

const result = await fireworks.launchTextSequence([
  'WISH BIG',
  { text: 'SHINE BRIGHT', overrides: { colors: ['#00BFFF', '#FFFFFF'] } },
  'CELEBRATE!'
], {
  gap: 250,
  clearBetween: true
});

fireworks.cancelTextSequence();

Sequence events are textsequencestart, textsequenceitem, textsequenceend, and textsequencecancel. Set textFirework.synchronizeExplosions: false to stagger multi-line arrivals instead of synchronizing them.

Sound

Sound is off by default. Call enableSound() from a click or tap handler to unlock browser audio, then use setMuted(true) or setOptions({ sound: { volume: 0.2 } }) for live control.

startButton.addEventListener('click', () => {
  fireworks.enableSound();
  fireworks.start();
});

The built-in realistic profile is fully procedural and adds positional launch whistles, low explosions, sharp reports, delayed crackle, a compressed master output, overlapping-voice protection, and a rhythmic grand-finale pattern. sound.stereo, sound.finaleRhythm, and sound.maxVoices are configurable; sound.volume accepts 0 through 1, and zero is a true mute. No audio files are bundled.

When enabled, performance.pauseWhenHidden, performance.pauseWhenOffscreen, and performance.respectReducedMotion pause invisible work and reduce animation density for visitors who request less motion. A manual pause() is kept separate from automatic pause reasons, so returning to a visible tab does not unexpectedly resume a user-paused show.

Contained mode uses the reliable Canvas 2D renderer automatically, avoiding transparent WebGL compositor failures in nested browser layers. Fullscreen mode remains WebGL-first. To test WebGL inside a particular container, explicitly pass renderer: { preferred: 'webgl2', preserveDrawingBuffer: true }; Canvas 2D remains the fallback.

The separate crisp-text canvas is hidden during ordinary shows and is displayed only while a crisp or hybrid text firework is active. It automatically hides again when the text phase completes, preventing transparent multi-canvas compositor failures in contained Chrome layouts.

Rocket paths fan naturally by default. Ordinary rockets launch within the middle 55% of the display at a random angle of up to 14 degrees left or right. Text rockets remain vertical, and the finale uses a wider 18-degree fan.

const fireworks = new GrandFireworks({
  speedMultiplier: 0.8, // run the complete firework simulation at 80% speed
  visuals: {
    trails: true,
    trailFade: 0.115,
    bloom: 1.25,
    rocketExhaust: true,
    explosionFlashes: true,
    starChance: 0.08,
    groupedSalvos: true,
    secondaryCrackle: true,
    zoom: 1 // 0.1–4; smaller values reveal a wider field of view
  },
  show: {
    launchSpread: 0.55,
    angleRange: 14,
    angleStrength: 1,
    textRocketAngle: 0,
    launchHorizon: 1, // total launch area, in screen widths
    minShellScale: 0.5, // each shell receives its own apparent scale
    maxShellScale: 1.5,
    grandFinaleShellChance: 0.05, // occasional layered finale shell, never a World Ender
    zAngleRange: 25, // 0–45° depth drift
    zAngleStrength: 0.8 // 0–3 depth drift multiplier
  }
});

Depth-staged horizon

visuals.zoom controls the visible field of view: values below 1 pull back to reveal more of the horizon, while values above 1 move closer. show.launchHorizon sets the total launch area in screen widths. show.minShellScale and show.maxShellScale give every firework its own apparent scale while keeping its rocket, exhaust, burst, and particles together.

Shells are staged as near, middle, or far. Distance affects apparent size, flight speed, burst height, stereo position, loudness, and a slight delay on distant launch and boom sounds. Tune depth drift with zAngleRange and zAngleStrength, or call fireworks.setZoom(0.5) to update the view live. See the Feature Demo panel for a live reference.

Run the dependency-free regression suite with npm test.