- Dharmagya
- panchang-ts docs
- Festivals
Festivals
panchang-ts · v5.0.0 · MIT
80+ festivals with stable keys, Smarta/Vaishnava Ekadashi handling, regional scoping across 21 states + Nepal, and the cacheable pre-computed festivals table.
Coverage spans Ekadashi (26 variants, Smarta/Vaishnava split via Dashami-viddha; the Smarta fast emits a deferralDate for Dwadashi), Pradosha, Sankranti and its regional variants (Pongal, Vishu, Baisakhi, Pohela Boishakh, Bihu, Uttarayan, Lohri…), canonical-time classical festivals (Janmashtami, Shivaratri, Ganesh Chaturthi, Diwali, Holi, Raksha Bandhan — Bhadra-aware, Karva Chauth, Akshaya Tritiya…), regional observances (Gudi Padwa, Gangaur, Teej variants, Onam, Chhath…), and monthly ones (Masik Shivaratri, Pushya days, Shravan Somvar…).
Reading festivals off a daily result
const r = getDailyPanchang(date, loc, { timezone: 330 })!;
r.festivals.forEach(f => {
// key: stable, language-independent id — 'diwali', 'makar_sankranti', …
// type: major | minor | ekadashi | smarta_ekadashi | vaishnava_ekadashi
// | pradosha | sankranti | eclipse
console.log(f.key, f.name, f.type, f.deferralDate);
});
// `name` is localized, so match on `key` — never on `name`.
const hasDiwali = r.festivals.some(f => f.key === 'diwali');For year listings without a daily loop, use the engine helpers from the main entry — computeFestivalsForYear(year, loc, opts) and computeFestivalsInRange(start, end, loc, opts) — documented in Calendar Conversion.
Regional scoping
region scopes regional variants to one Indian state. Pan-Indian festivals emit regardless.
// All regional variants (default):
getDailyPanchang(jan14, chennai, { timezone: 330 })!.festivals.map(f => f.name);
// → ["Sankranti","Makar Sankranti","Pongal","Uttarayan","Magh Bihu","Ayyappa Makara Jyothi"]
// Tamil Nadu only:
getDailyPanchang(jan14, chennai, { timezone: 330, region: 'tamil-nadu' })!
.festivals.map(f => f.name);
// → ["Sankranti","Makar Sankranti","Pongal"]
// Lohri fires on the Hindu day BEFORE Makara transit, in Punjab/Haryana/Himachal scope:
getDailyPanchang(jan13, amritsar, { timezone: 330, region: 'punjab' })!
.festivals.some(f => f.name === 'Lohri'); // trueFestivalRegion covers 21 Indian states + 'nepal' + 'all' (default). The legacy slugs 'tamil', 'bengal', 'north-india' are still accepted and mapped internally — the full union is in Types & Exports.
Pre-computed table — build your own and cache it
If you want festival dates without running the engine in your app, compute a table once with buildFestivalsTable, cache the JSON, and read it back through the engine-free panchang-ts/festivals entry point.
import { buildFestivalsTable } from 'panchang-ts'; // uses the engine
import {
readFestivalsForYear,
readFestivalsForDate,
readFestivalsYearRange,
} from 'panchang-ts/festivals'; // engine-free
// Build once — at your build time, or on first launch in the background.
const table = buildFestivalsTable({
location: { latitude: 25.3176, longitude: 82.9739 }, // Varanasi
timezoneOffsetMinutes: 330, // IST; -300 = US Eastern, 0 = UK
startYear: 2024,
endYear: 2031,
languages: ['en', 'hi'], // drop 'hi' to halve the size
referenceLocation: 'Varanasi',
});
// …persist `table` as JSON (disk / MMKV / your bundler's asset pipeline).
// Later reads are instant lookups — no engine, no ephemeris.
readFestivalsYearRange(table); // { start: 2024, end: 2031 }
readFestivalsForYear(table, 2026)!.length; // ~150 festival days
const diwali = readFestivalsForYear(table, 2026)!
.find(d => d.festivals.some(f => f.name === 'Diwali'))!.date;
readFestivalsForDate(table, diwali); // [Narak Chaturdashi, Diwali]
readFestivalsForDate(table, diwali, 'hi'); // [नरक चतुर्दशी, दिवाली]panchang-ts/festivals imports no astronomy code, so a client bundle that only reads a table never pulls in the engine. Keep buildFestivalsTable on the build/server side (or behind a one-time on-device warm-up) and ship only the JSON. Built tables are dictionary-encoded — a 10-year table is ~90 KB — and v1 (4.x) tables still read; only key is unavailable from them.
Eclipses are excluded here — visibility is location-dependent, so they get their own table at panchang-ts/eclipses (see Eclipses & Moon Phases).
Dating notes
Festivals resolve to a calendar day by tithi-at-sunrise, with canonical-time refinements where the tradition demands them. A few festivals have authorities that use other rules, where output can drift ±1 day — the exact list is documented in Accuracy. Karva Chauth / Dhanteras / Diwali emit with Purnimanta paksha naming.
