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

nanakshahi-jantri

v1.2.0

Published

Nanakshahi calendar (official Jantri) engine: pinned printed-Jantri data with a calibrated drik Bikrami astronomical fallback — sangrands, tithis, Gurpurabs.

Readme

nanakshahi-jantri

CI

Calendar engine for the Nanakshahi calendar as actually practised — the official printed Jantri (Amritsar): sangrands, massia/purnmashi, and every Gurpurab, itihasik dihada and bhagat sahiban da dihada. Pure JavaScript (Node ≥18), one dependency (astronomy-engine), no network access ever.

Use it for anything that needs Nanakshahi dates: apps, bots, widgets, ICS feeds (see nanakshahi-ical for the reference consumer), gurdwara displays, research.

Why this exists

The Jantri in current practice is the Bikrami calendar under Nanakshahi labels. Month starts are true sidereal sankrantis, so month lengths change every year (Jeth had 32 days in NS 557, Sawan has 32 in NS 558), and the Guru parkash/gurgaddi/joti-jot days move on Bikrami tithis (Parkash Guru Nanak Dev Ji = Katak purnmashi). Fixed date tables are wrong within a year or two. This engine instead layers:

  1. Pinned data (always wins) — dates extracted digit-by-digit from published Jantris, with source page citations. Bundled: NS 549 (2017-18), 557 (2025-26), 558 (2026-27).
  2. Computed fallback — a drik astronomical model for any other year, calibrated against every pinned data point: 36/36 sangrands, 25/25 massia+purnmashi, 132/132 tithi events. Every computed value is tagged estimated; events with no reliable rule are never guessed.
  3. User overrides — consumer-supplied additions/hides/renames, applied last.

Install

npm install nanakshahi-jantri        # once published
npm install janpreet/nanakshahi-jantri   # or straight from GitHub

API

import { Engine } from 'nanakshahi-jantri';

const engine = new Engine();

// Full year: months, massia/purnmashi, events — each tagged confirmed | estimated
const year = engine.buildYear(558);
year.months;              // [{ name:'Chet', start:'2026-03-14', days:31 }, ...]
year.events[0];           // { id, en, pa, category, date, ns, status, detail, ... }

// Solar table for any year (computed if unpinned)
engine.yearTable(560).sangrands;      // { Chet:'2028-03-14', ... }  (estimated)

// Date conversion (handles the varying month lengths)
const t = engine.yearTable(557);
engine.gregorianToNs('2025-05-30', t);   // { month:'Jeth', day:17, label:'17 Jeth' }
engine.nsToGregorian('Jeth', 32, t);     // '2025-06-14'  (32-day Jeth exists in 557)

// Events only
engine.eventsForYear(559);            // sorted, estimated-tagged

// Consumer overrides (object or path to JSON)
new Engine({ overrides: { add:[...], hide:['azadi-divas'], rename:{...} } });

Lower-level building blocks are exported too (Bikrami, sunriseUTC, tithiAt, findSankranti, …) for panchang-style use cases.

The model (what "estimated" means)

  • Solar: sun's sidereal longitude entering each rashi (Lahiri-type ayanamsa, 23.8532° at J2000); the sangrand is the sunrise-to-sunrise day at Amritsar containing the sankranti — a sankranti after midnight but before sunrise belongs to the previous civil day. This rule was forced by the data: 11 of the 36 pinned sangrands fall in that pre-dawn window.
  • Lunar: sunrise (udaya) tithi at Amritsar; purnimanta labels over amanta months; the amanta month containing the Mesha sankranti is Chet; a sankranti-less month is adhik and skipped; kshaya tithi → the day the tithi runs; vridhi tithi → the first day.
  • Festival rules: Bandi Chhor Divas = amavasya prevailing at pradosh (later evening when both qualify — the Jantri's own choice in the split-Diwali year 2025); Darbar Khalsa (Dussehra) = dashami overlapping aparahna (first day when both qualify). Estimated entries for these two carry a ±1-day note because panchang authorities genuinely disagree in split years.
  • Everything tunable lives in data/calibration.json; per-event rules in data/events.json. No code changes needed to recalibrate.

Adding a new Jantri year

Before the Jantri appears, print the estimate sheet to transcribe against:

npm run compare -- 559        # unpinned: full estimated year (sangrands, massia/purnmashi, events)

When the Jantri is published, add one file — data/pinned/ns<year>.json (copy the shape of ns558.json): 12 sangrands, massia/purnmashi days, and each event's printed date with a source page note. Then:

npm run compare -- 559        # pinned: diffs every pinned value against the model
npm test

Any DIFF is either a misread Gurmukhi digit (the look-alikes ੨/੭, ੫/੬/੯, ੮/੯ are the classic trap) or a genuine editorial change in the Jantri — both worth a second look before shipping. Real editorial changes can be recorded with a "divergence": "..." note on the pinned entry, which downgrades the DIFF to a documented warning.

Related work

  • drik-panchanga — general-purpose drik panchang in Python (Swiss Ephemeris). Same astronomy family; this package differs in being specialised to the Jantri's specific conventions and carrying pinned printed-Jantri data as ground truth.
  • nanakshahi-js — the original 2003 fixed arithmetic Nanakshahi calendar, which current Jantris no longer follow.

License

MIT