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

astromool

v1.2.0

Published

Official client for the AstroMool Vedic astrology API (Swiss Ephemeris charts, 90 calculators, PDF reports).

Downloads

63

Readme

astromool (JavaScript / TypeScript)

Official client for the AstroMool API: Vedic charts computed from the Swiss Ephemeris, the 90 astromool.com calculators, and the full PDF reports. Node.js 18+ (or any runtime with fetch). No dependencies. Types included.

import AstroMool from "astromool";            // or: const { AstroMool } = require("astromool");

const am = new AstroMool(process.env.ASTROMOOL_KEY);   // am_test_... while you build, am_live_... in production

const birth = { date: "1995-08-14", time: "10:35", tz_id: "Asia/Kolkata", lat: 25.5941, lon: 85.1376 };
const chart = await am.planets(birth);                 // { data, meta }
console.log(chart.data.ascendant.sign, chart.meta.ayanamsa);

const m = await am.calculators.run("manglik-dosha-calculator-by-date-of-birth", birth);
console.log(m.data.summary);                            // "Manglik - intensity 18/100" (string or null)

Every call resolves to the API's envelope { data, meta }. meta states the ayanamsa, the UTC offset used and the engine version; read meta.warnings - it flags things like a birth time that did not exist because of a DST change.

What each calculator needs

calculators.list() gives every calculator's input: for is birth (birth chart), today (today, read for the chart), year (send params.year / params.month), date (send params.date) or next (the next occurrence); params names the extra inputs it uses; basic_output: false means its answer is the full text.

// muhurat / festival lists: the place, and the year you want (default: this year at the place)
const v = await am.calculators.run("vivah-muhurat-dates", { lat: 28.61, lon: 77.21, tz_id: "Asia/Kolkata" }, { params: { year: 2027, month: 2 } });
// the reading behind a summary, when the calculator has one
const s = await am.calculators.run("sade-sati-calculator-by-date-of-birth", birth);
s.data.guidance?.sections?.forEach((x) => console.log(x.title, x.text ?? x.body ?? x.rows));

Methods

| Method | API | |---|---| | planets(birth, { ayanamsa, node }) | POST /v1/vedic/planets | | calculators.list() | GET /v1/calculators | | calculators.run(slug, person, { partner, params, detail }) | POST /v1/calculators/{slug} | | reports.create(slug, person, { partner, params, lang, webhookUrl, idempotencyKey }) | POST /v1/reports/{slug} | | reports.get(id) / reports.waitUntilReady(id, { timeout }) | GET /v1/reports/{id} | | reports.download(downloadUrl) | the signed PDF link (Uint8Array) | | geo.search(q, limit) / geo.timezone(tzId, date, time) | /v1/geo/* | | meta.ayanamsas(date), usage(), health() | |

Charts, dasha, panchang, matching and more (1.2.0)

const b = { date: "1995-08-14", time: "10:35", place: "Patna" };     // or lat/lon/tz_id; birth_time_unknown: true for a noon chart
await am.vedic.chart(b);            await am.vedic.divisional(b, "D9");      await am.vedic.ashtakavarga(b);
const svg = await am.vedic.chartImage(b, { style: "south", chart: "D9" });   // PNG: { format: "png" } -> Uint8Array
await am.dasha.vimshottari(b);      await am.dasha.yogini(b);
await am.panchang.day({ place: "Delhi" }, "2026-10-11");                     // .rahuKaal / .choghadiya / .hora
await am.match.ashtakoot(groom, bride);   await am.numerology.core("Asha Verma", "1995-08-14");
await am.dosha.check("mangal", b);  await am.dosha.summary(b);    await am.remedies.get("gemstone", b);
await am.transit.natal(b);          await am.kp.chart(b);         await am.western.natal(b);
await am.batch([{ path: "/v1/vedic/houses", body: b }, { method: "GET", path: "/v1/usage" }]);
await am.topic("/v1/muhurat/vivah", { person: { place: "Delhi" }, params: { year: 2027 } });   // any topic endpoint

Reports

const r = await am.reports.create("kundli-matching-by-date-of-birth", groom, { partner: bride, lang: "both" });
const ready = await am.reports.waitUntilReady(r.data.report_id);
fs.writeFileSync("report.pdf", await am.reports.download(ready.data.download_url));

reports.create sends an Idempotency-Key (generated if you do not pass one), so an automatic retry never creates a second report.

Errors and retries

Failures throw AstroMoolError with status, code (stable - see the errors page), detail (how to fix it), requestId, and field for input errors. The client retries rate_limited (waiting the server's Retry-After), 5xx answers and network errors - maxRetries (default 2). quota_exceeded is never retried.

try { await am.planets({ ...birth, date: "14/8/95" }); }
catch (e) { if (e instanceof AstroMoolError && e.code === "bad_date") { /* e.detail says the accepted formats */ } }

Options: new AstroMool(key, { baseUrl, timeout /* ms, default 30000 */, maxRetries, fetch }).

Webhooks

Pass webhookUrl to reports.create to be called when the report is ready. Verify each call with your webhook secret (dashboard > Keys) and the raw body:

import { verifyWebhook } from "astromool";
app.post("/astromool-hook", express.raw({ type: "application/json" }), (req, res) => {
  const event = verifyWebhook(req.body, req.get("X-AstroMool-Signature"), process.env.ASTROMOOL_WEBHOOK_SECRET);
  // event = { event: "report.ready" | "report.failed", report_id, status, download_url? }
  res.sendStatus(200);
});

Keys

Keep am_live_ keys on your server. In a browser use a widget key (am_pub_...), which only works from the domains you registered on it.

MIT licence.