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

ramadan-overlay

v0.1.3

Published

Lightweight Ramadan celebration overlay for any website — auto-triggered, multi-variant, framework-agnostic.

Readme

🌙 ramadan-overlay

Beautiful, auto-triggering Ramadan decorations for any website

npm version npm downloads gzip size License: MIT

CDN jsDelivr CDN unpkg

A lightweight TypeScript library that injects beautiful Ramadan decorations into any web app — zero dependencies, no build step required. Auto-detects Ramadan via the Hijri calendar with support for 10+ regional presets.

🔴 Live Demo & Config Generator →


✨ Features

  • 🗓️ Auto-detection — activates automatically during Ramadan using Hijri calendar conversion
  • 🎨 5 visual variants — Lanterns, Sparkles, Crescent & Stars, Geometric, Banner
  • 🌍 Region-aware — 10+ regional calendar presets with configurable day offsets
  • Zero dependencies — tree-shakeable, framework-agnostic
  • 🧩 All frameworks — React, Vue 3, Angular, Svelte, or plain HTML / CDN
  • 🎊 Confetti — on or off
  • 🖌️ Fully customizable — colors, opacity, density, position, and more

📦 Installation

npm install ramadan-overlay
# or
pnpm add ramadan-overlay
# or
yarn add ramadan-overlay

CDN (no bundler needed):

<!-- jsDelivr (recommended) -->
<script src="https://cdn.jsdelivr.net/npm/ramadan-overlay/dist/ramadan-overlay.min.js"></script>

<!-- unpkg -->
<script src="https://unpkg.com/ramadan-overlay/dist/ramadan-overlay.min.js"></script>

<script>
  RamadanOverlay.init({ variant: "lanterns", previewMode: true });
</script>

🚀 Quick Start

import { init } from "ramadan-overlay";

const overlay = init({
  variant: "lanterns", // 'lanterns' | 'sparkles' | 'crescent-stars' | 'geometric' | 'banner'
  previewMode: true, // force-show outside Ramadan (great for testing)
  opacity: 0.85,
});

// Ramadan state detected at mount time
console.log(overlay.state.dayNumber); // e.g. 5

// The overlay's root DOM element (null when not mounted)
console.log(overlay.container);

// Clean up when done
overlay.destroy();

🎨 Variants

| Variant | Description | | ---------------- | ------------------------------------------------------------------------------ | | lanterns | Classic hanging lanterns with customizable colors and styles (12 designs) | | sparkles | Glittering sparkle particles | | crescent-stars | Crescent moon and star motifs | | geometric | Decorative Islamic geometric patterns | | banner | Fixed greeting bar prepended to the page (pushes content down, not an overlay) |


⚙️ Options

General

| Option | Type | Default | Description | | ---------- | ---------- | --------------- | ---------------------------------------------------------------------------------------- | | variant | string | 'lanterns' | Visual decoration style | | position | string | 'both' | 'top' | 'bottom' | 'both' | 'full' | | opacity | number | 0.85 | Overlay opacity 01 | | colors | string[] | Ramadan palette | Custom CSS color array | | density | string | auto | 'low' | 'normal' | 'high' — defaults to 'low' on mobile, 'normal' on desktop | | zIndex | number | 9999 | CSS z-index of the overlay | | locale | string | 'en' | 'en' | 'ar' |

Behaviour

| Option | Type | Default | Description | | ------------- | --------- | ------- | ----------------------------------------- | | autoTrigger | boolean | true | Only show during Hijri Ramadan | | previewMode | boolean | false | Force display regardless of date | | confetti | string | 'on' | 'on' = fires every day of Ramadan, 'off' = disabled |

Date & Region

| Option | Type | Default | Description | | ----------------- | -------- | ------------ | ---------------------------------------------------------------------- | | region | string | 'standard' | Hijri calendar region preset (see table below) | | hijriAdjustment | number | 0 | Manual day offset — overrides region. Typical: -1, 0, +1, +2 |

Region presets

| Preset | Offset | Notes | | ----------- | :----: | -------------------------------------- | | standard | 0 | Umm al-Qura — Saudi Arabia (default) | | saudi | 0 | Alias for standard | | uae | 0 | Follows Saudi most years | | malaysia | 0 | JAKIM / follows Saudi | | egypt | +1 | Egyptian Dar al-Ifta | | turkey | +1 | Diyanet calculation | | pakistan | +1 | Moon-sighting committee | | indonesia | +1 | BIMAS calculation | | morocco | +1 | Ministry of Habous | | us | +1 | ISNA / Fiqh Council | | uk | +1 | Follows ISNA / local sighting |

Use hijriAdjustment for a custom numeric offset when no preset matches your region.

Lanterns variant

| Option | Type | Default | Description | | -------------- | -------- | ------------------------- | ----------------------------------------------------- | | lanternStyle | number | 0 | 112 pins a single design; 0 cycles through all | | ceilingColor | string | '#c9a84c' | Color of the horizontal ceiling bar | | ropeColor | string | '#c9a84c' | Color of the lantern strings | | glowColor | string | 'rgba(201,168,76,0.55)' | Drop-shadow / glow color |

Banner variant

| Option | Type | Default | Description | | ----------------- | -------- | ------------------------- | ----------------------------------------- | | bannerBg | string | 'rgba(15,15,20,0.92)' | Background color of the banner bar | | bannerTextColor | string | colors[0] | Greeting text color | | bannerIconColor | string | colors[1] | Color of the lantern icon beside the text | | bannerTextEn | string | built-in English greeting | Custom English greeting text | | bannerTextAr | string | built-in Arabic greeting | Custom Arabic greeting text |

Callbacks

| Option | Type | Description | | ---------------- | ------------------------------- | -------------------------------------------- | | onRamadanStart | (state: RamadanState) => void | Called once when Ramadan is detected at init | | onRamadanEnd | () => void | Called when overlay.destroy() is invoked |

import { init } from "ramadan-overlay";

init({
  variant: "lanterns",
  onRamadanStart: (state) => {
    console.log(`Ramadan ${state.hijriYear} — day ${state.dayNumber}`);
  },
  onRamadanEnd: () => {
    console.log("Overlay removed");
  },
});

📊 Checking Ramadan State

import { getRamadanState } from "ramadan-overlay";

// Today's state (standard calendar)
const { isRamadan, hijriYear, dayNumber } = getRamadanState();

// Optional: pass a specific date and/or a Hijri day offset
const state = getRamadanState(new Date("2025-03-01"), +1);

| Parameter | Type | Default | Description | | ----------------- | -------- | ------------ | ------------------------------------------------------------ | | date | Date | new Date() | Date to evaluate | | hijriAdjustment | number | 0 | Day offset applied before detection (positive = later start) |

| Field | Type | Description | | ----------- | --------- | ------------------------------------------ | | isRamadan | boolean | Whether today is within Ramadan | | hijriYear | number | Current Hijri year | | dayNumber | number | Day within Ramadan (130), 0 outside |


🧩 Framework Integrations

Hook

import { useRamadanOverlay } from "ramadan-overlay/react";

function App() {
  const { state } = useRamadanOverlay({ variant: "lanterns" });
  return state.isRamadan ? <p>Ramadan Mubarak!</p> : null;
}

Component — flat props

import { RamadanOverlay } from "ramadan-overlay/react";

function App() {
  return (
    <>
      <RamadanOverlay variant="lanterns" previewMode />
      <YourApp />
    </>
  );
}

Component — config object + render prop

function App() {
  return (
    <RamadanOverlay config={{ variant: "lanterns", previewMode: true }}>
      {(state) => state.isRamadan && <p>Ramadan Mubarak!</p>}
    </RamadanOverlay>
  );
}

Composable

<script setup>
import { useRamadanOverlay } from "ramadan-overlay/vue";
const { state } = useRamadanOverlay({ variant: "lanterns" });
</script>

<template>
  <p v-if="state.isRamadan">Ramadan Mubarak!</p>
</template>

Component — flat props

<template>
  <RamadanOverlay variant="crescent-stars" :previewMode="true" />
</template>

<script setup>
import { RamadanOverlay } from "ramadan-overlay/vue";
</script>

Component — :config object

<template>
  <RamadanOverlay
    :config="{ variant: 'geometric', previewMode: true }"
    @ramadan-start="onStart"
    @ramadan-end="onEnd"
  />
</template>

<script setup>
import { RamadanOverlay } from "ramadan-overlay/vue";
</script>

Standalone — individual inputs

import { RamadanOverlayDirective } from "ramadan-overlay/angular";

@Component({
  imports: [RamadanOverlayDirective],
  template: `
    <div ramadanOverlay variant="sparkles" [previewMode]="true"></div>
  `,
})
export class AppComponent {}

Standalone — [ramadanConfig] object input

@Component({
  imports: [RamadanOverlayDirective],
  template: `
    <div
      ramadanOverlay
      [ramadanConfig]="{ variant: 'lanterns', previewMode: true }"
    ></div>
  `,
})
export class AppComponent {}

NgModule-based app

import { RamadanOverlayModule } from "ramadan-overlay/angular";

@NgModule({ imports: [RamadanOverlayModule] })
export class AppModule {}

Action (use:ramadanOverlay)

<script>
  import { ramadanOverlay } from "ramadan-overlay/svelte";
</script>

<div use:ramadanOverlay={{ variant: "geometric", previewMode: true }}></div>

Composable (useRamadanOverlay)

<script>
  import { useRamadanOverlay } from "ramadan-overlay/svelte";
  const { state } = useRamadanOverlay({ variant: "geometric" });
</script>

{#if $state.isRamadan}<p>Ramadan Mubarak!</p>{/if}
<script src="https://cdn.jsdelivr.net/npm/ramadan-overlay/dist/ramadan-overlay.min.js"></script>
<script>
  RamadanOverlay.init({
    variant: "lanterns",
    region: "egypt",
    previewMode: true,
  });
</script>

📄 License

MIT © 3mr-5aled