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

vedic-muhurta

v0.1.0

Published

Electional-astrology (muhūrta) engine on top of vedic-panchanga — scan a date range for auspicious time windows for an activity, filtered by the person's janma rāśi & nakṣatra (Chandrabala, Tarabala). Ships a vehicle-purchase rule set.

Readme

vedic-muhurta

npm types license

Pick auspicious times (muhūrta) for an undertaking, on top of vedic-panchanga. Give it an activity (a rule set), the person it is for (janma rāśi + nakṣatra), a location and a date range — it scans the range and returns the time windows where every rule holds, already clear of Rāhu Kāla / Yamaganda / Gulika Kāla and of Viṣṭi (Bhadrā) karaṇa, each scored 0–100 with the reasons spelled out.

Ships one packaged activity, vehiclePurchase (vāhana kharīdī). Everything about it is plain data — copy and tweak it, or write your own activity the same way.

  • Person-aware — filters by Chandrabala (Moon's rāśi from the janma rāśi) and Tarabala (running nakṣatra from the janma nakṣatra)
  • Panchāṅga-aware — vāra, nakṣatra, tithi (by pakṣa ordinal), yoga, karaṇa
  • Windows, not just days — contiguous good stretches with start/end, duration, score, grade and per-factor reasons
  • Safe by default — Rāhu Kāla / Yamaganda / Gulika / Viṣṭi are always excluded; Abhijit Muhūrta earns a bonus
  • Extensible — an Activity is a JSON-ish object; bring your own for gṛha-praveśa, travel, etc.
  • Zero config astronomy — all positions come from vedic-panchanga (pure TypeScript, no native deps)
npm install vedic-muhurta
# vedic-panchanga is pulled in automatically

Quick start

import { findMuhurta, vehiclePurchase } from "vedic-muhurta";

const res = findMuhurta({
  activity: vehiclePurchase,
  person: { janmaRashi: "Simha", janmaNakshatra: "Magha" }, // names or 1-based indices
  from: "2026-09-05", // civil dates in `timezone`
  to: "2026-09-20",
  latitude: 28.6139,
  longitude: 77.209,
  timezone: "Asia/Kolkata",
});

for (const w of res.windows) {
  console.log(
    `${w.start.toLocaleString()} – ${w.end.toLocaleString()}  ` +
      `(${w.durationMinutes} min)  ${w.score}/100 ${w.grade}`,
  );
  console.log("   ✓ " + w.reasons.join("; "));
  if (w.cautions.length) console.log("   ! " + w.cautions.join("; "));
}

Already have a time in mind? Judge it directly:

import { evaluateMuhurta, vehiclePurchase } from "vedic-muhurta";

const v = evaluateMuhurta({
  activity: vehiclePurchase,
  person: { janmaRashi: "Simha", janmaNakshatra: "Magha" },
  at: new Date("2026-09-11T12:45:00+05:30"),
  latitude: 28.6139,
  longitude: 77.209,
  timezone: "Asia/Kolkata",
});

console.log(v.ok, v.score, v.grade);
console.log(v.blockers); // non-empty ⇢ why it was rejected

What you get

type FindMuhurtaResult = {
  activity: string;                       // "vehiclePurchase"
  person: { janmaRashi: string; janmaNakshatra: string }; // canonical names
  range: { from: string; to: string; timezone: string };
  windows: MuhurtaWindow[];               // earliest first, non-overlapping
  skippedDays: { date: string; reason: string }[]; // e.g. polar day
};

type MuhurtaWindow = {
  start: Date;
  end: Date;
  durationMinutes: number;
  score: number;                          // 0–100, mean across the window
  grade: "excellent" | "good" | "fair";
  reasons: string[];                      // factors that held all through
  cautions: string[];                     // minor negatives / factors that drifted
  panchangaAt: PanchangaSnapshot;         // tithi, vara, nakshatra, yoga, karana,
                                          // moonSign, chandrabala, tarabala at `start`
};

evaluateMuhurta returns one InstantVerdict:

type InstantVerdict = {
  ok: boolean;                            // false if any hard rule fails
  score: number;
  grade: "excellent" | "good" | "fair" | "rejected";
  reasons: string[];
  cautions: string[];
  blockers: string[];                     // hard-rule failures; non-empty exactly when !ok
  panchangaAt: PanchangaSnapshot;
};

Options (findMuhurta)

| Option | Type | Default | | -------------------- | -------------------------------------- | ------------------ | | activity | Activityrequired | — | | person | { janmaRashi, janmaNakshatra }required | — | | from / to | "yyyy-mm-dd" in timezonerequired | — | | latitude | number (−90…90) — required | — | | longitude | number (−180…180) — required | — | | timezone | IANA id | "Asia/Kolkata" | | ayanamsa | "lahiri" \| "raman" \| "kp" \| "fagan_bradley" | "lahiri" | | stepMinutes | sampling granularity | 15 | | minScore | drop windows below this | 55 | | minDurationMinutes | drop windows shorter than this | = stepMinutes | | dayStart / dayEnd| "HH:MM" clamp on the daily scan | sunrise → sunset |

person.janmaRashi accepts "Simha", "Leo", "सिंह" or 5; person.janmaNakshatra accepts "Magha", "मघा" or 10 (spacing and case are ignored).

Activities

An Activity is just data. Each cycle gets a Judgement{ good?, caution?, avoid? } of 1-based indices. good adds weight, caution subtracts a little (still eligible), avoid disqualifies the window outright. Anything unlisted is neutral.

import type { Activity } from "vedic-muhurta";

const grihaPravesh: Activity = {
  name: "grihaPravesh",
  label: { iast: "Griha Pravesha", english: "house-warming" },
  vara: { good: [2, 4, 5, 6], avoid: [3, 7] },        // 1 = Sunday … 7 = Saturday
  nakshatra: { good: [4, 5, 7, 13, 15, 17, 22, 26, 27] },
  tithi: { good: [2, 3, 5, 7, 10, 11, 13], avoid: [4, 9, 14], avoidAmavasya: true },
  yoga: { avoid: [17, 27] },                          // Vyatipata, Vaidhriti
  karana: { avoid: [7] },                             // Vishti / Bhadra
  chandrabala: { good: [1, 3, 6, 7, 10, 11], caution: [2, 5, 9], avoid: [4, 8, 12] },
  tarabala: { good: [2, 4, 6, 8, 9], caution: [1], avoid: [3, 5, 7] },
  // weights: { nakshatraGood: 20 },  // optional per-activity overrides
};

Tithi is judged by ordinal within the pakṣa (1–15), so one list covers both Śukla and Kṛṣṇa; avoidAmavasya / avoidPurnima target those two days specifically. See src/activities/vehicle-purchase.ts for the shipped rule set with notes on each list.

Lower-level exports

import {
  resolveRashi, resolveNakshatra, rashiName, nakshatraName,
  chandrabala, tarabala, TARA_NAMES,
  evaluatePanchanga, snapshot, grade, DEFAULT_WEIGHTS,
} from "vedic-muhurta";

evaluatePanchanga(panchanga, activity, janmaRashi1, janmaNakshatra1) applies the rules to a Panchanga you already computed (compute it with the time option so each aṅga is the one running at your instant).

How a window is scored

Starting from DEFAULT_WEIGHTS.base (50), each factor adds or subtracts:

  • vāra favourable +16, mixed −8, avoided → rejected
  • nakṣatra favourable +14, not on the list −6, avoided → rejected
  • tithi favourable +10, mixed −4, Riktā / Amāvasyā (per activity) → rejected
  • yoga mixed −10, Vyatīpāta / Vaidhṛti (per activity) → rejected
  • karaṇa not Viṣṭi +2, Viṣṭi → rejected
  • Chandrabala strong +14, weak −3, 4th/8th/12th → rejected
  • Tarabala favourable +12, Janma −6, Vipat/Pratyari/Vadha → rejected
  • inside Abhijit Muhūrta +6; inside Rāhu Kāla / Yamaganda / Gulikarejected

Score is clamped to 0–100. grade is excellent ≥ 82, good ≥ 68, else fair. Override any weight per activity via activity.weights.

Accuracy & limitations

  • Panchāṅga level only — no lagna, no navāṁśa, no planetary aspects. This finds a clean muhūrta by the almanac factors; it is not a full electional chart.
  • Discrete sampling — windows are found by stepping stepMinutes through the day, so an edge is accurate to one step, not to the exact aṅga boundary. Use a smaller stepMinutes for tighter edges (at a linear cost in time).
  • Rule lists are a consensus — the vehiclePurchase lists follow commonly published vāhana-muhūrta guidance. Traditions differ; adjust the Activity.
  • Datesfrom / to are civil dates in timezone, resolved via noon UTC; fine for every common zone, off by a day only for offsets beyond ±12 h.
  • Astronomy accuracy is whatever vedic-panchanga provides (almanac-grade, aṅga boundaries within ~a minute).

License

MIT