Skip to content
Documentation · all sections

Getting Started

panchang · v5.4.0 · MIT

Install the package, compute your first daily panchang, and read the times it gives you back. Every example is shown in TypeScript and Go.

Install

npm install panchang-ts
# or: pnpm add panchang-ts / yarn add panchang-ts

The npm package ships ESM and CJS builds with TypeScript types, targets ES2020 and has no runtime dependencies. It runs in Node.js, modern browsers and React Native (Hermes). See Errors & Compatibility for the version floors.

The Go module needs Go 1.22 or newer and also has no dependencies. It has two packages: github.com/ishankgupta95/panchang/source/go/v5/panchang holds the engine, and github.com/ishankgupta95/panchang/source/go/v5/types holds the data types it takes and returns. Most programs import both.

Neither build downloads an ephemeris file or makes a network call. The positions are worked out in process.

Quick start

import { getDailyPanchang } from 'panchang-ts';

const result = getDailyPanchang(
  new Date('2025-01-14T00:00:00Z'),           // January 14, 2025 (05:30 IST)
  { latitude: 23.1765, longitude: 75.7885 },  // Ujjain, India
  { timezone: 330 },                          // IST = UTC+5:30 = 330 minutes
);
// → DailyPanchangResult | null. Null only when no sunrise-to-sunrise day starts
//   on that date (polar latitudes, or an offset far from local solar time).
//   Narrow with `if (!result) return;`.

console.log(result!.angas.tithis[0].name);          // "Krishna Pratipada"
console.log(result!.angas.nakshatras[0].name);      // "Punarvasu"
console.log(result!.angas.vara.name);               // "Mangalawara"
console.log(result!.calendar.chandramasa.name);     // "Magha"
console.log(result!.calendar.samvat.vikramSamvat);  // 2081

You pass three things: the calendar date, the place, and options. The date is any instant inside the day you want: it is read in your timezone, and its time of day is ignored. A new Date(2025, 0, 14) is midnight in the host's zone, which on a host east of IST is still 13 January in IST. The only option you must set is timezone. Give it minutes from UTC (330 for IST) or an IANA name like 'Asia/Kolkata'. In Go, wrap the offset as panchang.OffsetMinutes(330). Everything else has a default, and Options & Localization lists the lot.

location has no default and never will. A panchang computed for the wrong place does not look wrong. You get a complete, plausible result with some dates off by a day. If you really have no coordinates, resolveLocation gives you a named reference frame and tells you which one you got, so you can label the output the way a printed panchang names the city it was computed for.

Three things to know in Go

  • Create a session once with panchang.New() and reuse it for every call. A session is not safe for concurrent use, so give each goroutine its own.
  • Calls return three values: the result, an ok flag, and an err. Check err first, then ok. A false ok is not a failure. It means no sunrise-to-sunrise Hindu day starts on that date, which happens at polar latitudes and, since 5.4, on a day a fixed offset far from local solar time leaves without a sunrise. It matches the null that TypeScript returns there.
  • An error is a *types.PanchangError and carries a stable Code you can branch on, which panchang.IsCode(err, types.ErrInvalidDate) matches. The Err* constants are types.ErrorCode values rather than errors, so errors.Is cannot take one. The codes are listed in Errors & Compatibility.

Field names are the TypeScript names in Go casing, so result.angas.tithis[0].name is day.Angas.Tithis[0].Name. The rest of this site uses the TypeScript spelling in prose and shows the Go spelling in the code.

Reading output times

Every Date in a result is a real instant, so .getTime() is the correct epoch millisecond. Next to it sits a *Local companion: an ISO 8601 string with the offset attached. That string is what you show a user.

Go publishes the same pair. The instant is a JSDate: call .Time() for a time.Time (new in 5.4), .Ms() for epoch milliseconds or .ISOString() for UTC. The *Local fields are plain strings, exactly as in TypeScript.

result!.sun.rise;         // Date — 2025-01-14T01:40:16.566Z (the actual moment)
result!.sun.riseLocal;    // "2025-01-14T07:10:16.566+05:30"
result!.inauspicious.rahuKalam.start;       // Date
result!.inauspicious.rahuKalam.startLocal;  // string

// Just the wall clock:
result!.sun.riseLocal.slice(11, 16);   // "07:10"

// Anything else works too, because the Date is genuinely correct:
new Intl.DateTimeFormat('en-IN', { timeZone: 'Asia/Kolkata', timeStyle: 'short' })
  .format(result!.sun.rise);           // "7:10 am"

For an instant you worked out yourself, formatInZone renders it the same way. The offset is a whole number of minutes (an int in Go). In TypeScript a fraction throws INVALID_TIMEZONE since 5.4, where 5.3 printed a garbled offset.

import { formatInZone } from 'panchang-ts';

const noon = new Date((result!.sun.rise.getTime() + result!.sun.set.getTime()) / 2);
formatInZone(noon, result!.timezone.offsetMinutes);  // "2025-01-14T12:35:59.017+05:30"

moon.rise and moon.set can be null. The Moon does not rise or set on every calendar day, and that is normal. moon.riseLocal and moon.setLocal are null exactly when they are. Go models this with pointers: Moon.Rise is a *JSDate and Moon.RiseLocal is a *string, so check for nil before you read them.

The result is grouped

DailyPanchangResult has seven groups plus a few top-level fields. The group tells you where to look:

GroupHolds
sunrise / set / nextRise (+ *Local), day and night lengths, the Sun's siderealLongitude and nakshatra
moonrise / set (+ *Local), the Moon's siderealLongitude and rashi
angasthe five limbs — tithis, nakshatras, yogas, karanas, vara
calendarmasa (solar), chandramasa (lunar), samvat
muhurtasabhijit, brahma, vijaya, godhuli, nishita, amritKala, madhyahna, pratahSandhya, sayahnaSandhya, doGhati
inauspiciousrahuKalam, gulikaKalam, yamaganda, durMuhurta, varjyam, bhadra, gandaMula, panchaka, panchakaInfo, panchakaRahita
periodschoghadiya, hora, gowri

Top level: date, location, timezone, ayanamsa, specialYogas, anandadiYoga, festivals, eclipse, chandraBalam, tarabala.

getDailyPanchang vs getInstantPanchang

What you wantCall
A day: calendar, festivals, muhurtas, time slots (Choghadiya, Hora, Gowri), eclipses with sutakgetDailyPanchang
A moment: what is running right now, or casting a birth chartgetInstantPanchang

getInstantPanchang reuses the same group names for the part an instant can answer: sun, moon, angas, calendar and inauspicious. There is no muhurtas or periods group, because those belong to a whole Hindu day. Its results carry no *Local fields either. The call takes no timezone, so there is no zone to render a wall clock in.

When things go wrong

  • Bad input throws a typed PanchangError with a stable code. In Go it is a *types.PanchangError with the same Code. Both are listed in Errors & Compatibility, along with the few TypeScript checks that throw a plain RangeError. Since 5.4 an Invalid Date throws INVALID_DATE instead of hanging getSunrise.
  • At polar latitudes getDailyPanchang and getInstantPanchang return null instead of throwing. Without a sunrise there is no Hindu day to describe. Since 5.4 that includes the last sunless day of a polar night, which used to return the next day's panchang.
  • On React Native with an older Hermes, pass timezone as a number. IANA names need Intl. Performance shows the two-pass rendering pattern.