Skip to content
Documentation · all sections

Birth Charts

panchang · v5.4.0 · MIT

Planetary positions, Lagna, Bhava under three house systems, D1 and seven divisional charts, and planetary dignity.

Planetary positions

computePlanetaryPositions gives you all nine grahas at one moment, sidereal. Each one is a GrahaPosition: rashi, nakshatra and pada, degree within the sign, and a retrograde flag.

The library does not carry rashi or nakshatra names for this call. You pass your own name lookups as the third and fourth arguments.

import { computePlanetaryPositions, GRAHA_ABBR } from 'panchang-ts';

// The library does not name rashis or nakshatras here — supply the lists.
const RASHI = ['Mesha','Vrishabha','Mithuna','Karka','Simha','Kanya',
               'Tula','Vrischika','Dhanus','Makara','Kumbha','Meena'];
const NAK = ['Ashwini','Bharani','Krittika','Rohini','Mrigashira','Ardra','Punarvasu',
             'Pushya','Ashlesha','Magha','Purva Phalguni','Uttara Phalguni','Hasta',
             'Chitra','Swati','Vishakha','Anuradha','Jyeshtha','Mula','Purva Ashadha',
             'Uttara Ashadha','Shravana','Dhanishtha','Shatabhisha',
             'Purva Bhadrapada','Uttara Bhadrapada','Revati'];
const nakName = (i: number) => NAK[i], rashiName = (i: number) => RASHI[i];

const at = new Date('2026-09-02T00:00:00Z');
const g = computePlanetaryPositions(at, 'lahiri', nakName, rashiName);
console.log(g.jupiter.rashi.name);                 // Karka
console.log(g.jupiter.degreeInRashi.toFixed(2));   // 19.67
console.log(g.jupiter.nakshatra.name);             // Ashlesha
console.log(g.jupiter.nakshatra.pada);             // 1
console.log(g.saturn.isRetrograde);                // true
console.log(GRAHA_ABBR['Jupiter']);                // Ju

// True node (sharper Rahu/Ketu) — the fifth argument.
const gT = computePlanetaryPositions(at, 'lahiri', nakName, rashiName, 'true');
console.log(g.rahu.siderealLongitude.toFixed(4), gT.rahu.siderealLongitude.toFixed(4));
// 305.0122 305.6174

isRetrograde is always false for the Sun and Moon, and always true for Rahu and Ketu. The node model defaults to the mean node; the last argument switches it to the true node.

Lagna and Bhava

computeLagna gives you the ascendant — rashi, nakshatra and pada. computeBhava gives you the twelve house cusps and the MC longitude, under whichever house system you ask for.

import { computeLagna, computeBhava, PanchangError } from 'panchang-ts';

const birth = new Date('1995-08-15T05:30:00Z');
const loc   = { latitude: 28.6139, longitude: 77.2090 };

const lagna = computeLagna(birth, loc, 'lahiri', 'en');
console.log(lagna.rashi.name, lagna.nakshatra.name, lagna.pada);   // Tula Chitra 4

// houseSystem: 'whole-sign' (default) | 'equal' | 'placidus-kp'.
const houses = computeBhava(birth, loc, { houseSystem: 'whole-sign' });
console.log(houses.system, houses.houses[0].cuspLongitude);        // whole-sign 180
console.log(houses.mcLongitude.toFixed(4));                        // 96.8589

// Placidus-KP is undefined beyond the polar circles (about ±66.56°).
try {
  computeBhava(birth, { latitude: 78, longitude: 15 }, { houseSystem: 'placidus-kp' });
} catch (e) {
  console.log((e as PanchangError).code);                          // CIRCUMPOLAR
}

In Go the house system is a named types.HouseSystem constant rather than a bare string, and an empty field means whole-sign. In TypeScript an omitted houseSystem means whole-sign too, but an empty string is an unknown house system.

Rashi chart and divisional charts

computeRashiChart casts the D1: lagna, bhava, and the nine grahas placed in houses. chart.planets is the ordered list. chart.byPlanet is the same nine placements keyed by graha, so you can read one without scanning the list.

computeNavamsa gives you the D9. computeDivisionalChart gives you any of D2 Hora, D3 Drekkana, D7 Saptamsa, D9 Navamsa, D10 Dasamsa, D12 Dwadasamsa and D30 Trimsamsa.

import { computeRashiChart, computeNavamsa, computeDivisionalChart, computeDignity }
  from 'panchang-ts';

const birth = new Date('1995-08-15T05:30:00Z');
const loc   = { latitude: 28.6139, longitude: 77.2090 };
const opts  = { houseSystem: 'whole-sign' } as const;

// byPlanet is the keyed lookup; planets is the ordered list.
const d1 = computeRashiChart(birth, loc, opts);
console.log(d1.divisional, d1.byPlanet.Mars.house);                      // D1 12
console.log(d1.byPlanet.Jupiter.house, d1.byPlanet.Saturn.isRetrograde); // 2 true
const jup = d1.planets.find(p => p.planet === 'Jupiter')!;
console.log('scan:', jup.planet, jup.rashi.name, jup.house);             // scan: Jupiter Vrischika 2

// Divisional charts (D2, D3, D7, D9, D10, D12, D30).
const d9  = computeNavamsa(birth, loc, opts);
const d10 = computeDivisionalChart(birth, loc, 'D10', opts);
const d30 = computeDivisionalChart(birth, loc, 'D30', opts);
console.log(d9.divisional,  d9.lagnaRashi.name);    // D9 Vrischika
console.log(d10.divisional, d10.lagnaRashi.name);   // D10 Vrischika
console.log(d30.divisional, d30.lagnaRashi.name);   // D30 Mesha

// Planetary dignity (BPHS Ch. 3-4).
console.log(computeDignity('Mars', 0));   // moolatrikona
console.log(computeDignity('Mars', 9));   // exalted
console.log(computeDignity('Sun',  6));   // debilitated

computeRashiChart returns a BirthChart: divisional, lagna, bhava, planets, byPlanet. The divisional helpers return a DivisionalChart — divisional, lagnaRashi, planets — whole-sign anchored to their own lagna, with no cusps and no keyed lookup. So the helpers downstream (Ashtakavarga, yogas, doshas, Arudhas, Argala) all take a d1 straight from computeRashiChart. Shadbala and Bhava Bala are the exception: they take the birth date and location, like computeRashiChart itself.

OptionValuesDefault
houseSystem'whole-sign' · 'equal' · 'placidus-kp''whole-sign'
ayanamsaall five — 'lahiri', 'raman', 'krishnamurti', 'true-chitra', 'thirukanitham''lahiri'
language'en' · 'hi''en'
nodeTypeRahu/Ketu node model — 'mean' · 'true''mean'

An unknown house system, divisional or graha name throws a PanchangError with code INVALID_INPUT. For a house system or divisional the message lists the values it accepts, for example unknown divisional "D60"; expected one of D2, D3, D7, D9, D10, D12, D30. Before 5.4 TypeScript failed on these with a raw TypeError; Go already returned the error. An Invalid Date throws INVALID_DATE, including in computePlanetaryPositions, which used to return NaN longitudes for one.