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

panchanga

v0.1.1

Published

Drik Panchanga (Smārta, pūrṇimānta) engine for HSNA — computes tithi, vara, nakshatra, yoga, karana, festivals and eclipses from astronomical first principles.

Readme

panchanga

Drik Panchanga (Smārta, pūrṇimānta) engine for the HSNA website.

A dependency-light TypeScript library that computes the Hindu lunisolar calendar — the five aṅgas (vāra, tithi, nakṣatra, yoga, karaṇa), the lunar month, and sidereal / ayanāṁśa values — and resolves Hindu festival dates, all from astronomical first principles via astronomy-engine. No lookup tables, no remote API.

Status: pre-1.0 (0.1.0), under active development. The grammar and public API may still change.

Features

  • The five aṅgas — vāra (sunrise-to-sunrise weekday), tithi, nakṣatra, yoga, and karaṇa (including Viṣṭi / Bhadra, with its Mukha/Pucchā split and Vāsa), plus the pūrṇimānta / amānta lunar month with adhika (leap) and kṣaya (lost) month detection.
  • Daily pañcāṅgadailyPanchanga(date, loc) bundles all five aṅgas (each resolved at sunrise, with its end-time) and the day's sun/moon instants into one record.
  • Grahaṇa (eclipses) — solar & lunar eclipse type, contact timings, local visibility, and sūtak windows (9h lunar / 12h solar) for any year and place.
  • Astronomy primitives — Lahiri ayanāṁśa (IAU 1976 precession), sidereal longitudes and Sun rāśi, new moons, solar ingress (saṅkrānti).
  • Time & kāla windows — timezone/DST-safe sunrise, sunset and moonrise, the muhūrta windows (pūrvāhna, madhyāhna, aparāhna, pradoṣa, niśīta, brahma-muhūrta, …), and the weekday day-part periods Rāhu Kāla, Yamaganda, Gulika, and Abhijit.
  • Festival engine — a compact rule grammar (Observance) and a pure, testable pervasion-day selector that resolves ~195 observances to civil dates and never silently drops: every miss is explained in diagnostics. Selection conventions are first-class — udaya vs window-fraction precedence, a nearest-window fallback, an adhika:"prefer-adhika" leap-month policy, Bhadra exclusion, and nakṣatra- and weekday-anchored festivals (Onam, Varalakṣmī).
  • Validated at two well-separated longitudes against Drik Panchang fixtures (2026): New Delhi and Calgary (the HSNA temple's city). All 24 core festivals and all 24 in-year Ekādaśīs match Drik's Calgary calendar exactly, including the −1-day localisation shifts; the handful of remaining differences are convention edges, pinned and documented in the tests.

Requirements

  • ESM only ("type": "module") — use import, not require.
  • Node.js ≥ 18 to consume (the build targets ES2022). Building/testing from source needs Node ≥ 22.12 (Vitest 4).

Install

npm install panchanga

Quick start

The full pañcāṅga for a day

import { dailyPanchanga } from "panchanga";
import type { GeoLocation } from "panchanga";

const newDelhi: GeoLocation = {
  latitude: 28.6139,
  longitude: 77.209,
  timeZone: "Asia/Kolkata", // IANA tz id
};

const p = dailyPanchanga(new Date("2026-01-23"), newDelhi);

console.log(p.date, p.vara.name);            // 2026-01-23 Shukravara
console.log(p.tithi.paksha, p.tithi.name);   // shukla Panchami
console.log(p.nakshatra.name);               // Purva Bhadrapada
console.log(p.yoga.name);                    // Parigha
console.log(p.karana.name);                  // Bava
console.log(p.month.purnimanta);             // Magha
console.log(p.muhurta.rahuKala);             // { start: "...Z", end: "...Z" } — Rāhu Kāla

Each running aṅga (tithi, nakṣatra, yoga, karaṇa) is the one prevailing at sunrise and carries an endsAt (ISO-UTC) marking when it gives way to the next; the record also includes sunrise, sunset, moonrise, and the day's muhurta windows (Rāhu Kāla, Yamaganda, Gulika, Abhijit).

Compute festival dates for a year and location

import { computeFestivals, allRules } from "panchanga";
import type { GeoLocation } from "panchanga";

const newDelhi: GeoLocation = {
  latitude: 28.6139,
  longitude: 77.209,
  timeZone: "Asia/Kolkata", // IANA tz id
};

const { results, diagnostics } = computeFestivals(2026, newDelhi, {
  rules: allRules(2026),
});

for (const f of results) {
  if (f.date) console.log(f.date, f.id, "—", f.monthLabel.purnimanta);
}
// 2026-01-14 makar-sankranti — Magha
// 2026-03-04 holi            — Chaitra
// 2026-04-02 hanuman-jayanti — Vaishakha
// …

// Anything that could not be resolved is explained, never dropped:
diagnostics.forEach((d) => console.warn(d));

Each FestivalResult carries the civil date (YYYY-MM-DD in loc's timezone), a map of key instants (tithi start/end, window start/end, …) as ISO-UTC strings, both month labels, and per-rule diagnostics.

Read raw calendar elements at an instant

import {
  tithiBoundaries, nakshatraAt, NAKSHATRA_NAMES, karanaAt, lunarMonth,
} from "panchanga";

const when = new Date("2026-01-23T12:00:00Z");

const tithi = tithiBoundaries(when);          // { number: 1..30, start: Date, end: Date }
const nak   = NAKSHATRA_NAMES[nakshatraAt(when)];
const kar   = karanaAt(when);                 // karaṇa name
const month = lunarMonth(when, { system: "purnimanta" });

console.log(tithi.number, nak, kar, month.purnimantaLabel, month.adhika);

Sidereal / ayanāṁśa

import { ayanamsha, siderealSunRashi } from "panchanga";

const t = new Date("2026-06-24T00:00:00Z");
ayanamsha(t);        // Lahiri ayanāṁśa in degrees (≈ 24.2° in 2026)
siderealSunRashi(t); // sidereal rāśi index of the Sun: 0 = Mesha … 11 = Mīna

API overview

The public surface (see src/index.ts) is layered:

1. Ayanāṁśa & siderealayanamsha, siderealLongitude, siderealSunRashi, normalize360, LAHIRI_ANCHOR_J2000_DEG.

2. Time, vāra & kāla windowsriseSet, moonrise, sunset, varaAt, sunriseWindow / pratahkala, purvahna, madhyahna, aparahna, pradosha, nishita, brahmaMuhurta, arunodaya, rahuKala, yamaganda, gulikaKala, abhijitMuhurta, sankrantiPunyaKala, plus timezone helpers (localDayString, startOfLocalDayUTC, nextLocalDayStartUTC) and VARA_NAMES. Types: GeoLocation, TimeWindow, Vara.

3. Calendar elementstithiAt, tithiBoundaries, nakshatraAt, nakshatraBoundaries, yogaAt, yogaBoundaries, karanaAt, karanaIndexAt, karanaName, karanaBoundaries, bhadraIntervals, bhadraSplit, elongation, newMoons, solarIngress, lunarMonth. Name tables: TITHI_NAMES, NAKSHATRA_NAMES, YOGA_NAMES, MOVABLE_KARANAS, LUNAR_MONTH_NAMES.

4. Daily aggregatordailyPanchanga(date, loc)DailyPanchanga (the five aṅgas at sunrise + sun/moon instants + month label + the day's Rāhu/Yama/Gulika/Abhijit muhūrtas).

4b. Grahaṇa (eclipses)lunarEclipses(year, loc?), solarEclipses(year, loc?) → eclipse type, contact phases (ISO-UTC IsoWindows), local visibility, and sūtak. Types: LunarEclipse, SolarEclipse, GrahanKind.

5. Festival enginecomputeFestivals, computeFestival, selectDayByPervasion (the pure selector), and the rule data: CORE_RULES plus the generators ekadashiRules, sankashtiRules, pradoshRules, masikShivaratriRules, purnimaVratRules, purnimaSnanaRules, amavasyaRules, sankrantiRules, oneOffFestivalRules, regionalFestivalRules (each (year)), CHHATH_RULE, and allRules(year). Grammar types: Observance, FestivalRule, FestivalResult, Kala, TithiRef, Paksha. Observance kinds include tithi-pervades (with udaya / max-window-fraction precedence, an adhika:"prefer-adhika" leap-month policy, and a nearest-window fallback), solar-ingress, moonrise, solar-arghya, derived, nakshatra-pervades (Onam), and weekday-relative (Varalakṣmī).

allRules(year) covers ~195 observances: the 24 major festivals, every Ekādaśī, Sankaṣṭī Caturthī, Pradoṣa Vrata, Masik Śivarātri, Pūrṇimā Vrata (vrat) and Pūrṇimā snāna-dāna, Amāvāsyā, all 12 Sankrāntis, Chhath, the HSNA one-offs (Ugadi, the Teej trio, Nag Panchami, Rath Yatra, Tulsi Vivah, Anant Chaturdashi, …), and ~21 further regional festivals & jayantis (Ratha Saptamī, Narasimha/Paraśurāma/Sītā/Gaṅgā jayantis, Vat Sāvitrī, Vishwakarma, Kālī Chaudas, Onam, Varalakṣmī, …) — validated against Drik Panchang's New Delhi and Calgary calendars (residual cases are ±1-day convention edges, pinned in the tests).

The rule grammar

A festival is authored as a FestivalRule whose observance.kind declares how its civil date is resolved:

| kind | Resolves by | Examples | |---|---|---| | tithi-pervades | A tithi pervading a kāla window on the chosen day, picked by a precedence policy (max-window-fraction, udaya, first, second). Optional nakshatra filter, avoidKarana: "vishti" (Bhadra), adhika: "prefer-adhika" (leap-month policy), and a fallback (previous-day / next-day / nearest-window) | most lunar festivals | | solar-ingress | The Sun's sidereal ingress into a rāśi | Makar Saṅkrānti, Vishwakarma | | moonrise | Tithi live at moonrise | Karva Chauth, Sankaṣṭī | | solar-arghya | Tithi at sunset and the next sunrise | Chhath | | derived | An offset from another festival | Holi = Holikā + 1 | | nakshatra-pervades | The day a named nakṣatra is at sunrise while the Sun is in a given rāśi | Onam (Śravaṇa in Siṃha) | | weekday-relative | The latest weekday before another festival's date | Varalakṣmī (Friday before Śrāvaṇa Pūrṇimā) |

allRules(year) returns CORE_RULES plus every recurring and regional observance generated for that year (see the generators listed under API overview → 5).

Scope of validation

This package computes panchanga values via astronomy-engine and is validated for conformance to Drik Panchang (Smārta, pūrṇimānta) for the locations and years covered by test/fixtures. It has not been independently verified by a traditional pandit or Jyotisha authority — verify computed values against your local authority before ritual use.

Development

npm install      # install dependencies
npm test         # vitest run — unit suites + Drik-Panchang conformance
npm run build    # tsc → dist/ (ESM .js + .d.ts + source/declaration maps)

Tests live in test/ (~370 cases): per-module unit suites plus the Drik-Panchang conformance checks — conformance.test.ts (2026 New Delhi) and five Calgary suites (the HSNA temple's city) whose EXPECTED dates are transcribed from Drik Panchang's Calgary calendar (geoname-id 5913490): conformance-calgary.test.ts (24 core festivals), -vratas (Ekādaśī, Saṅkaṣṭī, Pūrṇimā vrat & snāna, Amāvāsyā, minor Saṅkrāntis), -oneoff (HSNA regional festivals) and -regional (21 further festivals/jayantis incl. Onam & Varalakṣmī). All 24 core festivals and all 24 in-year Ekādaśīs match Drik Calgary exactly; the few remaining ±1 convention edges and definitional differences are pinned and documented. The suites also assert the localisation invariant — every Calgary date is within ±1 day of New Delhi — which is what catches a wrong convention (a single locale can't, since many conventions agree there).

Known convention edges

Most differences from Drik Panchang are not errors — they are points where the tradition itself admits more than one reckoning, or where the engine intentionally follows HSNA. The ones to be aware of:

  • Pūrṇimā / Amāvāsyā — vrat vs snāna. purnima-vrat-* is the moonrise vrat day; purnima-snana-* is the next-morning snāna-dāna day Drik lists as "X Purnima". At far-western longitudes these are usually one civil day apart — both are correct, for different observances.
  • Gauṇa (Vaiṣṇava) Ekādaśī — not yet emitted. When an Ekādaśī is Daśamī-viddha, Vaiṣṇavas fast the next day ("Gauṇa"). The engine emits only the Smārta date; the second-day reckoning is future work.
  • Ganga Dussehra, Balram Jayanti — definitional, follow HSNA. Ganga Dussehra uses the adhika Jyeṣṭha when present (matching Drik); Balram Jayanti follows HSNA's Kṛṣṇa-Ṣaṣṭhī rather than Drik's Śukla-Ṣaṣṭhī.
  • Maha Navami (Durga) — Sandhi rule, +1 known diff. Drik can place Navamī on the Aṣṭamī-udaya day via the Sandhi-Pūjā convention, which the generic tithi grammar does not express.
  • Pinned ±1 edges: Kārtika Pūrṇimā snāna, Sarva-Pitṛ Amāvāsyā, Mithuna Saṅkrānti, Phulera Dooj, Hariyali Teej / Nag Panchami / Kansh Vadh (New Delhi). Each is a two-day tithi straddling sunrise where the day-attribution convention is genuinely borderline; the tests pin the produced date so any change is surfaced consciously.

Tech stack

  • Language: TypeScript 6 (strict), ES2022 target, NodeNext modules, ESM-only.
  • Runtime dependency: astronomy-engine — the only one; provides ephemeris (Sun/Moon position, rise/set, moon-phase search, precession).
  • Tooling: tsc for the build, Vitest 4 for tests. No bundler, linter, or CI.

License

MIT © 2026 Hindu Society of North America