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

holi-overlay

v1.0.0

Published

🎨 A stunning Holi festival overlay with colorful water balloons, pichkaari streams, and ambient color effects. Drop-in integration for any website.

Readme


🎬 What It Does

Holi Overlay renders a full-screen canvas animation featuring:

| Effect | Description | |--------|-------------| | 🎈 Water Balloons | Colorful balloons fly in from all 4 sides, burst on-screen with splash physics | | πŸ’¦ Pichkaari Streams | Water gun streams shoot across the screen with dense particle trails | | 🌈 Ambient Gradients | Breathing, pulsing color gradients in every corner for atmosphere | | ✨ Splash Particles | Realistic burst particles (water droplets + powder clouds) on balloon impact |

The overlay sits on top of your existing page using position: fixed with pointer-events: none, so your website remains fully interactive beneath it.


πŸ“¦ Installation

Method 1: CDN (No Build Tools Required)

The fastest way β€” just paste two lines before </body>:

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start();</script>

Method 2: npm / yarn / pnpm

# npm
npm install holi-overlay

# yarn
yarn add holi-overlay

# pnpm
pnpm add holi-overlay

Then import in your JavaScript:

import HoliOverlay from 'holi-overlay';

HoliOverlay.start();

Method 3: Self-Hosted

Download dist/holi-overlay.umd.js from this repository and serve it from your own server:

<script src="/assets/js/holi-overlay.umd.js"></script>
<script>HoliOverlay.start();</script>

πŸš€ Quick Start

Simplest Integration (2 Lines)

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start();</script>

Auto-Start via Data Attributes (Zero JavaScript)

<script 
  src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"
  data-autostart
  data-max-balloons="10"
  data-duration="30000"
></script>

Available data-* attributes:

| Attribute | Maps To | |-----------|---------| | data-autostart | Enables auto-start on page load | | data-z-index | zIndex option | | data-opacity | opacity option | | data-max-balloons | maxBalloons option | | data-max-pichkaaris | maxPichkaaris option | | data-duration | duration option (ms) |

Start with Custom Options

HoliOverlay.start({
  maxBalloons: 12,
  maxPichkaaris: 3,
  opacity: 0.9,
  duration: 60000  // Auto-stop after 60 seconds
});

πŸ”— Framework Integration Guides

React

import { useEffect } from 'react';
import HoliOverlay from 'holi-overlay';

function App() {
  useEffect(() => {
    const overlay = HoliOverlay.start({
      maxBalloons: 12,
      duration: 30000
    });

    // Cleanup on unmount
    return () => overlay.stop();
  }, []);

  return <div>Your App Content</div>;
}

Controlled by state:

import { useEffect } from 'react';
import HoliOverlay from 'holi-overlay';

function FestiveApp({ showHoli }) {
  useEffect(() => {
    if (showHoli) {
      HoliOverlay.start();
    } else {
      HoliOverlay.stop();
    }
    return () => HoliOverlay.stop();
  }, [showHoli]);

  return <div>...</div>;
}

Next.js (App Router)

// components/HoliFestive.tsx
'use client';

import { useEffect } from 'react';
import HoliOverlay from 'holi-overlay';

export default function HoliFestive() {
  useEffect(() => {
    const overlay = HoliOverlay.start({
      zIndex: 99999,
      maxBalloons: 10,
      maxPichkaaris: 3
    });
    return () => overlay.stop();
  }, []);

  return null;
}
// layout.tsx or page.tsx
import HoliFestive from './components/HoliFestive';

export default function Layout({ children }) {
  return (
    <>
      {children}
      <HoliFestive />
    </>
  );
}

Next.js (Pages Router)

// pages/_app.tsx
import type { AppProps } from 'next/app';
import dynamic from 'next/dynamic';

const HoliFestive = dynamic(() => import('../components/HoliFestive'), {
  ssr: false
});

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />
      <HoliFestive />
    </>
  );
}

Vue.js 3 (Composition API)

<script setup>
import { onMounted, onUnmounted } from 'vue';
import HoliOverlay from 'holi-overlay';

let overlay;

onMounted(() => {
  overlay = HoliOverlay.start({
    maxBalloons: 12,
    duration: 60000
  });
});

onUnmounted(() => {
  if (overlay) overlay.stop();
});
</script>

Vue.js 2 (Options API)

import HoliOverlay from 'holi-overlay';

export default {
  data() {
    return { overlay: null };
  },
  mounted() {
    this.overlay = HoliOverlay.start({ maxBalloons: 12 });
  },
  beforeDestroy() {
    if (this.overlay) this.overlay.stop();
  }
};

Angular

// holi-overlay.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import HoliOverlay from 'holi-overlay';

@Component({
  selector: 'app-holi-overlay',
  template: ''
})
export class HoliOverlayComponent implements OnInit, OnDestroy {
  private overlay: any;

  ngOnInit() {
    this.overlay = HoliOverlay.start({
      maxBalloons: 10,
      duration: 60000
    });
  }

  ngOnDestroy() {
    if (this.overlay) this.overlay.stop();
  }
}

Svelte

<script>
  import { onMount, onDestroy } from 'svelte';
  import HoliOverlay from 'holi-overlay';

  let overlay;

  onMount(() => {
    overlay = HoliOverlay.start({ maxBalloons: 12 });
  });

  onDestroy(() => {
    if (overlay) overlay.stop();
  });
</script>

WordPress

Option A: Via functions.php

// Add to your theme's functions.php
function add_holi_overlay() {
    wp_enqueue_script(
        'holi-overlay',
        'https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js',
        array(),
        '1.0.0',
        true
    );
    wp_add_inline_script(
        'holi-overlay',
        'HoliOverlay.start({ maxBalloons: 10, duration: 60000 });'
    );
}
add_action('wp_enqueue_scripts', 'add_holi_overlay');

Option B: Via Theme Footer

Paste in your theme's footer.php before </body>:

<script
  src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"
  data-autostart
  data-duration="60000"
></script>

Option C: Via Custom HTML Block (Gutenberg)

Add a "Custom HTML" block to any page/post:

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start({ duration: 30000 });</script>

Shopify

Add to your theme's theme.liquid before </body>:

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start({ duration: 60000 });</script>

Wix (Custom Code)

Go to Settings β†’ Custom Code β†’ Body End and paste:

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start({ duration: 30000 });</script>

Squarespace

Go to Settings β†’ Advanced β†’ Code Injection β†’ Footer and paste:

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start({ duration: 30000 });</script>

Google Tag Manager

Create a Custom HTML tag with trigger "All Pages":

<script src="https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js"></script>
<script>HoliOverlay.start({ duration: 30000 });</script>

βš™οΈ Configuration Options

Pass an options object to HoliOverlay.start():

HoliOverlay.start({
  zIndex: 99999,
  opacity: 0.95,
  maxBalloons: 15,
  maxPichkaaris: 4,
  colors: [...],
  duration: 0,
  container: 'body'
});

| Option | Type | Default | Description | |--------|------|---------|-------------| | zIndex | number | 99999 | CSS z-index of the overlay canvas. Set higher if your site uses high z-index values. | | opacity | number | 0.95 | Overall opacity of the overlay (0 = invisible, 1 = fully opaque). | | maxBalloons | number | 15 | Maximum number of water balloons on screen simultaneously. Higher = more festive. | | maxPichkaaris | number | 4 | Maximum number of water gun streams simultaneously. Higher = more chaotic. | | colors | Array<{r,g,b}> | 9 Holi colors | Custom color palette. Each color is an object with r, g, b (0-255). | | duration | number | 0 | Auto-stop after N milliseconds. 0 means run forever until .stop() is called. | | container | string | body | CSS selector for the container where the canvas is appended. |

Preset Examples

Subtle / Minimal:

HoliOverlay.start({
  maxBalloons: 5,
  maxPichkaaris: 1,
  opacity: 0.5
});

Party Mode / Maximum Festivity:

HoliOverlay.start({
  maxBalloons: 25,
  maxPichkaaris: 8,
  opacity: 1.0
});

Brand Colors:

HoliOverlay.start({
  colors: [
    { r: 255, g: 0, b: 100 },   // Brand pink
    { r: 0, g: 200, b: 255 },   // Brand blue
    { r: 255, g: 200, b: 0 },   // Brand gold
    { r: 100, g: 255, b: 100 }  // Brand green
  ]
});

Timed Celebration (30 seconds):

HoliOverlay.start({
  maxBalloons: 12,
  duration: 30000  // Stops after 30 seconds
});

πŸ”Œ API Reference

Static Methods (Singleton)

These manage a single global overlay instance:

// Start the overlay with optional configuration
const controller = HoliOverlay.start(options?);

// Stop and remove the overlay
HoliOverlay.stop();

// Toggle on/off β€” calls start(options) if stopped, or stop() if running
HoliOverlay.toggle(options?);

// Check if the overlay is currently running
HoliOverlay.isRunning();  // β†’ boolean

Factory Method (Multiple Instances)

For advanced use cases (e.g., different configurations on different pages):

// Create a controller without starting it
const controller = HoliOverlay.create(options?);

// Manually start
controller.start();

// Check status
controller.isRunning();  // β†’ boolean

// Toggle
controller.toggle();

// Stop and cleanup
controller.stop();

Properties

HoliOverlay.version         // β†’ '1.0.0'
HoliOverlay.defaultColors   // β†’ Array of 9 default Holi colors

πŸ— Building from Source

Prerequisites

  • Node.js 14+ installed

Steps

# Clone the repository
git clone https://github.com/your-username/holi-overlay.git
cd holi-overlay

# Build distribution files
npm run build

# Start the demo page
npm run dev

Build Output

| File | Size | Purpose | |------|------|---------| | dist/holi-overlay.js | ~25 KB | ESM β€” Full version with comments (primary) | | dist/holi-overlay.min.js | ~15 KB | ESM β€” Minified (tree-shakeable) | | dist/holi-overlay.umd.js | ~27 KB | UMD β€” For CDN <script> tags (browser global) | | dist/holi-overlay.cjs | ~27 KB | CJS β€” For Node.js require() | | dist/holi-overlay.d.ts | ~2.2 KB | TypeScript type declarations |


πŸ”§ Publishing to npm

First-Time Setup

  1. Create an account at npmjs.com
  2. Login from your terminal:
    npm login
  3. Update package.json with your info:
    • Set repository.url to your GitHub repo URL
    • Set homepage to your demo/docs URL
    • Set bugs.url to your GitHub issues URL

Publish

# Build first (runs automatically via prepublishOnly)
npm publish

After publishing, anyone can install it with:

npm install holi-overlay

And the CDN link becomes active at:

https://cdn.jsdelivr.net/npm/holi-overlay@latest/dist/holi-overlay.umd.js

πŸ›‘ Performance & Best Practices

How It Performs

  • Particle budget: Pichkaari streams are capped at 600 particles each, splashes capped at 30 simultaneously β€” prevents runaway memory usage
  • GC-friendly: Hot render loop uses in-place array filtering instead of Array.filter() to avoid garbage collection pauses
  • Debounced resize: Window resize handler is debounced at 100ms to prevent layout thrashing during window drag
  • requestAnimationFrame: All animation runs at native screen refresh rate, pauses when tab is inactive
  • pointer-events: none: The canvas never intercepts clicks β€” your page stays fully interactive
  • aria-hidden: true: Screen readers properly ignore the decorative canvas

Recommended Settings for Production

// Safe defaults for production use
HoliOverlay.start({
  maxBalloons: 8,       // Low enough for decent frame rate on mobile
  maxPichkaaris: 2,     // Each stream creates many particles
  opacity: 0.8,         // Subtle enough to not hide content
  duration: 30000,      // Auto-stop after 30 seconds
  zIndex: 99999         // Sits above most elements
});

Mobile Considerations

The overlay works on mobile devices, but for the best experience:

// Detect mobile and reduce intensity
const isMobile = window.innerWidth < 768;
HoliOverlay.start({
  maxBalloons: isMobile ? 5 : 15,
  maxPichkaaris: isMobile ? 1 : 4,
  duration: 20000
});

🧩 Advanced Usage

Toggle with a Button

<button onclick="HoliOverlay.toggle()">🎨 Toggle Holi Mode</button>

Schedule for a Specific Date

const today = new Date();
const holiDate = new Date(today.getFullYear(), 2, 14); // March 14 (adjust yearly)

if (today.toDateString() === holiDate.toDateString()) {
  HoliOverlay.start({ duration: 60000 });
}

Trigger on User Action

document.getElementById('celebrate-btn').addEventListener('click', () => {
  if (!HoliOverlay.isRunning()) {
    HoliOverlay.start({ duration: 15000 });
  }
});

Multiple Overlays (Advanced)

const overlay1 = HoliOverlay.create({ maxBalloons: 5, opacity: 0.5 });
const overlay2 = HoliOverlay.create({ maxBalloons: 10, opacity: 0.8 });

overlay1.start();
overlay2.start();

// Later
overlay1.stop();
overlay2.stop();

πŸ“ Project Structure

holi-overlay/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ holi-overlay.js    # Core library (native ES Module)
β”‚   └── react.jsx          # React wrapper component
β”œβ”€β”€ dist/                  # Built files (auto-generated)
β”‚   β”œβ”€β”€ holi-overlay.js    # ESM (primary)
β”‚   β”œβ”€β”€ holi-overlay.min.js # ESM (minified)
β”‚   β”œβ”€β”€ holi-overlay.umd.js # UMD (CDN / <script> tags)
β”‚   β”œβ”€β”€ holi-overlay.cjs   # CJS (Node.js require)
β”‚   └── holi-overlay.d.ts  # TypeScript declarations
β”œβ”€β”€ demo.html              # Interactive demo / landing page
β”œβ”€β”€ build.js               # Zero-dependency build script (ESM)
β”œβ”€β”€ package.json           # type: "module", conditional exports
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ LICENSE
└── README.md

🀝 Contributing

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

πŸ“„ License

MIT Β© Vikas

Free for personal and commercial use. Attribution appreciated but not required.