A comprehensive TypeScript/JavaScript library for astronomical calculations with traditional Hindu Panchanga support, powered by Swiss Ephemeris.
- ✨ Complete Panchanga Calculations: Tithi, Nakshatra, Yoga, Karana, Vara
- 🌍 Location-based Calculations: Accurate sunrise/sunset times
- 🌙 Lunar Calendar: Moon phases and lunar mansions
- ⏰ Rahu Kaal: Inauspicious time periods
- 🎯 High Accuracy: Uses Swiss Ephemeris for precise calculations
- 📦 Easy to Use: Simple API for integration into any project
- 🔧 TypeScript Support: Full type definitions included
npm install @bidyashish/panchang
const { getPanchanga, getPanchangaReport } = require('@bidyashish/panchang');
// Calculate Panchanga for a specific date and location
const date = new Date('2024-01-01T12:00:00Z');
const latitude = 12.972; // Bangalore, India
const longitude = 77.594;
const timezone = 'Asia/Kolkata';
// Get Panchanga data
const panchanga = getPanchanga(date, latitude, longitude, timezone);
console.log(`Tithi: ${panchanga.tithi.name}`);
console.log(`Nakshatra: ${panchanga.nakshatra.name}`);
console.log(`Yoga: ${panchanga.yoga.name}`);
console.log(`Sunrise: ${panchanga.sunrise?.toLocaleTimeString()}`);
// Get formatted report
const report = getPanchangaReport(date, latitude, longitude, timezone);
console.log(report);
import {
getPanchanga,
AstronomicalCalculator,
PanchangaInput,
PanchangaOutput
} from '@bidyashish/panchang';
const input: PanchangaInput = {
date: new Date('2024-01-01T12:00:00Z'),
location: {
latitude: 12.972,
longitude: 77.594,
timezone: 'Asia/Kolkata'
}
};
const calculator = new AstronomicalCalculator();
const panchanga: PanchangaOutput = calculator.calculatePanchanga(input);
console.log(`Today's Tithi: ${panchanga.tithi.name}`);
console.log(`Completion: ${panchanga.tithi.percentage.toFixed(1)}%`);
calculator.cleanup();
import React, { useState, useEffect } from 'react';
import { getPanchanga, getPanchangaReport } from '@bidyashish/panchang';
function PanchangaWidget({ latitude, longitude, timezone }) {
const [panchanga, setPanchanga] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchPanchanga() {
try {
setLoading(true);
const data = await getPanchanga(new Date(), latitude, longitude, timezone);
setPanchanga(data);
} catch (error) {
console.error('Error fetching Panchanga:', error);
} finally {
setLoading(false);
}
}
fetchPanchanga();
}, [latitude, longitude, timezone]);
if (loading) return <div>Loading Panchanga...</div>;
if (!panchanga) return <div>Error loading Panchanga</div>;
return (
<div className="panchanga-widget">
<h2>Today's Panchanga</h2>
<p><strong>Tithi:</strong> {panchanga.tithi.name}</p>
<p><strong>Nakshatra:</strong> {panchanga.nakshatra.name}</p>
<p><strong>Vara:</strong> {panchanga.vara.name}</p>
<p><strong>Yoga:</strong> {panchanga.yoga.name}</p>
<p><strong>Karana:</strong> {panchanga.karana.name}</p>
</div>
);
}
export default PanchangaWidget;
<template>
<div class="panchanga-component">
<h2>Panchanga Calculator</h2>
<div v-if="loading">Loading...</div>
<div v-else-if="panchanga" class="panchanga-data">
<div class="element">
<span class="label">Tithi:</span>
<span class="value">{{ panchanga.tithi.name }}</span>
</div>
<div class="element">
<span class="label">Nakshatra:</span>
<span class="value">{{ panchanga.nakshatra.name }}</span>
</div>
<div class="element">
<span class="label">Vara:</span>
<span class="value">{{ panchanga.vara.name }}</span>
</div>
<button @click="refreshPanchanga">Refresh</button>
</div>
</div>
</template>
<script>
import { getPanchanga } from '@bidyashish/panchang';
export default {
name: 'PanchangaComponent',
props: {
latitude: { type: Number, required: true },
longitude: { type: Number, required: true },
timezone: { type: String, required: true }
},
data() {
return {
panchanga: null,
loading: false
};
},
async created() {
await this.fetchPanchanga();
},
methods: {
async fetchPanchanga() {
this.loading = true;
try {
this.panchanga = await getPanchanga(
new Date(),
this.latitude,
this.longitude,
this.timezone
);
} catch (error) {
console.error('Error:', error);
} finally {
this.loading = false;
}
},
async refreshPanchanga() {
await this.fetchPanchanga();
}
}
};
</script>
const express = require('express');
const { getPanchanga, getPanchangaReport } = require('@bidyashish/panchang');
const app = express();
app.get('/api/panchanga', async (req, res) => {
try {
const { lat, lng, tz, date, format } = req.query;
if (!lat || !lng || !tz) {
return res.status(400).json({
error: 'Missing required parameters: lat, lng, tz'
});
}
const targetDate = date ? new Date(date) : new Date();
if (format === 'report') {
const report = await getPanchangaReport(
targetDate,
parseFloat(lat),
parseFloat(lng),
tz
);
res.type('text/plain').send(report);
} else {
const panchanga = await getPanchanga(
targetDate,
parseFloat(lat),
parseFloat(lng),
tz
);
res.json(panchanga);
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => {
console.log('Panchanga API running on port 3000');
});
# Install globally for CLI access
npm install -g @bidyashish/panchang
# Or use with npx (no installation needed)
npx @bidyashish/panchang --lat 28.6139 --lng 77.2090 --tz Asia/Kolkata
# Get JSON output
npx @bidyashish/panchang --lat 28.6139 --lng 77.2090 --tz Asia/Kolkata --format json
# Specific date
npx @bidyashish/panchang --lat 28.6139 --lng 77.2090 --tz Asia/Kolkata --date 2025-07-19
Calculate Panchanga for a specific date and location.
Parameters:
date
(Date): The date for calculationlatitude
(number): Latitude in degrees (-90 to 90)longitude
(number): Longitude in degrees (-180 to 180)timezone
(string): IANA timezone identifier (e.g., 'Asia/Kolkata')
Returns: PanchangaOutput
object
Generate a formatted text report.
Returns: Formatted string report
For advanced usage and multiple calculations:
const calculator = new AstronomicalCalculator();
// Calculate Panchanga
const panchanga = calculator.calculatePanchanga({
date: new Date(),
location: {
latitude: 28.6139, // Delhi
longitude: 77.2090,
timezone: 'Asia/Kolkata'
}
});
// Calculate planetary positions
const positions = calculator.calculatePlanetaryPositions(
new Date(),
['Sun', 'Moon', 'Mars', 'Jupiter']
);
// Always cleanup when done
calculator.cleanup();
The PanchangaOutput
object contains:
{
date: Date;
vara: {
name: string; // e.g., "Friday"
number: number; // 1-7
};
tithi: {
name: string; // e.g., "Saptami"
number: number; // 1-15
percentage: number; // 0-100
paksha: 'Shukla' | 'Krishna';
};
nakshatra: {
name: string; // e.g., "Revati"
number: number; // 1-27
pada: number; // 1-4
};
yoga: {
name: string; // e.g., "Siddha"
number: number; // 1-27
};
karana: {
name: string; // e.g., "Bava"
number: number; // 1-60
};
moonPhase: string; // e.g., "Waxing Crescent"
sunrise: Date | null;
sunset: Date | null;
rahuKaal: {
start: Date | null;
end: Date | null;
} | null;
}
Test the library accuracy against DrikPanchang.com reference data:
# Quick verification (recommended)
npm run verify
# Comprehensive testing of all functions
npm run example
The verification scripts test with July 20, 2025 in Kelowna, BC, Canada and achieve 80% perfect accuracy against DrikPanchang.com (4/5 Panchanga elements match exactly).
const { AstronomicalCalculator } = require('@bidyashish/panchang');
const calculator = new AstronomicalCalculator();
const date = new Date();
const locations = [
{ name: 'Delhi', lat: 28.6139, lon: 77.2090, tz: 'Asia/Kolkata' },
{ name: 'Mumbai', lat: 19.0760, lon: 72.8777, tz: 'Asia/Kolkata' },
{ name: 'New York', lat: 40.7128, lon: -74.0060, tz: 'America/New_York' }
];
locations.forEach(loc => {
const panchanga = calculator.calculatePanchanga({
date,
location: { latitude: loc.lat, longitude: loc.lon, timezone: loc.tz }
});
console.log(`${loc.name}: ${panchanga.tithi.name}, ${panchanga.nakshatra.name}`);
});
calculator.cleanup();
function getPanchangaForWeek(startDate, location) {
const calculator = new AstronomicalCalculator();
const results = [];
for (let i = 0; i < 7; i++) {
const date = new Date(startDate);
date.setDate(date.getDate() + i);
const panchanga = calculator.calculatePanchanga({ date, location });
results.push({
date: date.toDateString(),
tithi: panchanga.tithi.name,
nakshatra: panchanga.nakshatra.name,
tithiEndTime: panchanga.tithi.endTime // Transition times available
});
}
calculator.cleanup();
return results;
}
const { getPanchanga } = require('@bidyashish/panchang');
const date = new Date('2025-07-20T12:00:00.000-07:00');
const panchanga = getPanchanga(date, 49.888, -119.496, 'America/Vancouver');
// Access detailed data for each element
console.log('Tithi Details:', {
name: panchanga.tithi.name,
number: panchanga.tithi.number,
percentage: panchanga.tithi.percentage,
endTime: panchanga.tithi.endTime
});
console.log('Nakshatra Details:', {
name: panchanga.nakshatra.name,
number: panchanga.nakshatra.number,
pada: panchanga.nakshatra.pada,
endTime: panchanga.nakshatra.endTime
});
Here are timezone identifiers for common locations:
- India:
Asia/Kolkata
- USA East:
America/New_York
- USA West:
America/Los_Angeles
- UK:
Europe/London
- Australia:
Australia/Sydney
- Japan:
Asia/Tokyo
- Germany:
Europe/Berlin
City | Latitude | Longitude |
---|---|---|
Delhi, India | 28.6139 | 77.2090 |
Mumbai, India | 19.0760 | 72.8777 |
New York, USA | 40.7128 | -74.0060 |
London, UK | 51.5074 | -0.1278 |
Tokyo, Japan | 35.6762 | 139.6503 |
Panchanga (Sanskrit: पञ्चाङ्ग) means "five limbs" and refers to the five key elements:
- Vara (वार): Day of the week
- Tithi (तिथि): Lunar day (1-15, in Shukla/Krishna paksha)
- Nakshatra (नक्षत्र): Lunar mansion (1-27)
- Yoga (योग): Astronomical combination of Sun and Moon (1-27)
- Karana (करण): Half of a tithi (1-60) What we HAVE:
Vara (Weekday): Monday ✅ Tithi: Dwadashi with percentage ✅ Paksha: Krishna (Waning) ✅ Nakshatra: Mrigashira with Pada ✅ Yoga: Dhruva ✅ Karana: Gara ✅ Sunrise/Sunset times ✅ Moonrise/Moonset times ✅ Lunar months (Amanta/Purnimanta) ✅ Shaka/Vikrama Samvat ✅ Sun sign/Moon sign ✅ Rahu Kaal, Gulikai Kaal, Yamaganda ✅ Planetary positions ✅
Additional Elements:
- Paksha: Lunar fortnight (Shukla = waxing, Krishna = waning)
- Rahu Kaal: Inauspicious time period each day
- Node.js 16.0.0 or higher
- Swiss Ephemeris data files (automatically handled)
Each Swiss Ephemeris file covers a period of 600 years; there are 50 planetary files, 50 Moon files for the whole time range of almost 30.000 years and 18 main-asteroid files for the time range of 10.800 years.
The file names are as follows:
Planetary file | Moon file | Main asteroid file | Time range |
---|---|---|---|
seplm06.se1 | semom06.se1 | seasm06.se1 | 601 BCE -- 2 BCE |
sepl_00.se1 | semo_00.se1 | seas_00.se1 | 1 BCE -- 599 CE |
sepl_06.se1 | semo_06.se1 | seas_06.se1 | 600 CE -- 1199 CE |
sepl_12.se1 | semo_12.se1 | seas_12.se1 | 1200 CE -- 1799 CE |
sepl_18.se1 | semo_18.se1 | seas_18.se1 | 1800 CE -- 2399 CE |
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details.
- Swiss Ephemeris library for accurate astronomical calculations
- Traditional Vedic astronomical principles
- Based on the drik-panchanga Python implementation by Satish BD