Developer GuideNode.jsswissephLahiri Ayanamsa

Swiss Ephemeris in Node.js
swisseph npm · Full Setup Guide

Install swisseph, compute sidereal planetary positions with Lahiri ayanamsa, calculate nakshatra and pada, and derive the ascendant — all in Node.js. Production-ready code examples included.

Use Our API Instead →API Reference
💡
Want to skip the setup?
Our API runs Swiss Ephemeris locally on our servers. You get the same precision with a single HTTP call — no native addons, no build tools, no ephemeris files to manage. Start free →

Step 1 — Install swisseph

terminal
# Install swisseph (requires build tools: node-gyp, python)
npm install swisseph

# On macOS (if you see gyp errors):
xcode-select --install
npm install swisseph

# On Ubuntu/Debian:
sudo apt-get install -y python3 build-essential
npm install swisseph

# Verify installation
node -e "const swe = require('swisseph'); console.log(swe.SE_SUN);"
# Should print: 0

Step 2 — Compute Sidereal Planet Positions

planets.js
const swisseph = require('swisseph')
const path = require('path')

// Point to ephemeris data files
swisseph.swe_set_ephe_path(
  path.join(process.cwd(), 'node_modules/swisseph/ephe')
)

// Convert birth date/time to Julian Day Number
function toJulianDay(year, month, day, hourDecimal) {
  return swisseph.swe_julday(year, month, day, hourDecimal, swisseph.SE_GREG_CAL)
}

// Get sidereal (Vedic) planet position with Lahiri ayanamsa
function getPlanetSidereal(jd, planetId) {
  // Set Lahiri ayanamsa (most common in Vedic astrology)
  swisseph.swe_set_sid_mode(swisseph.SE_SIDM_LAHIRI, 0, 0)

  const flags = swisseph.SEFLG_SWIEPH | swisseph.SEFLG_SIDEREAL
  const result = swisseph.swe_calc_ut(jd, planetId, flags)

  if (result.flag === swisseph.ERR) {
    throw new Error(`Ephemeris error for planet ${planetId}`)
  }

  return {
    longitude: result.longitude,  // 0-360 degrees
    latitude:  result.latitude,
    speed:     result.longitudeSpeed,
    retrograde: result.longitudeSpeed < 0,
  }
}

// Example: Get Sun and Moon for Mumbai birth chart
const jd = toJulianDay(1990, 6, 15, 8.5)  // 15 Jun 1990, 08:30 IST

const sun  = getPlanetSidereal(jd, swisseph.SE_SUN)
const moon = getPlanetSidereal(jd, swisseph.SE_MOON)
const mars = getPlanetSidereal(jd, swisseph.SE_MARS)

console.log('Sun longitude:', sun.longitude.toFixed(4))   // e.g. 60.3421 (Taurus)
console.log('Moon retrograde:', moon.retrograde)           // false
console.log('Mars retrograde:', mars.retrograde)           // true/false

Step 3 — Derive Nakshatra, Pada, and Sign

nakshatra.js
// Convert longitude to nakshatra, pada, and sign
const NAKSHATRAS = [
  '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 SIGNS = [
  'Aries','Taurus','Gemini','Cancer','Leo','Virgo',
  'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces'
]

function parsePosition(longitude) {
  const nakshatraIndex = Math.floor(longitude / (360 / 27))
  const pada           = Math.floor((longitude % (360 / 27)) / (360 / 108)) + 1
  const signIndex      = Math.floor(longitude / 30)
  const degreeInSign   = longitude % 30

  return {
    nakshatra:      NAKSHATRAS[nakshatraIndex],
    pada,
    sign:           SIGNS[signIndex],
    degree:         degreeInSign.toFixed(2),
    fullDegree:     longitude.toFixed(4),
  }
}

// Example usage
const sunPos = parsePosition(sun.longitude)
console.log(sunPos)
// { nakshatra: 'Mrigashira', pada: 4, sign: 'Taurus', degree: '0.34' }

Step 4 — Calculate the Ascendant (Lagna)

ascendant.js
// Compute ascendant (lagna) — requires birth location
function getAscendant(jd, latitude, longitude, ayanamsa = swisseph.SE_SIDM_LAHIRI) {
  swisseph.swe_set_sid_mode(ayanamsa, 0, 0)

  // swe_houses returns house cusps and ASC/MC
  const houses = swisseph.swe_houses(jd, latitude, longitude, 'P') // 'P' = Placidus

  // Subtract ayanamsa for sidereal ascendant
  const ayanamsaValue = swisseph.swe_get_ayanamsa_ut(jd)
  let siderealAsc = houses.ascendant - ayanamsaValue
  if (siderealAsc < 0) siderealAsc += 360
  if (siderealAsc >= 360) siderealAsc -= 360

  return parsePosition(siderealAsc)
}

// Mumbai: lat 19.0760, lon 72.8777
const ascendant = getAscendant(jd, 19.0760, 72.8777)
console.log('Ascendant:', ascendant.sign, ascendant.degree + '°')

Swiss Ephemeris + Node.js — FAQs

Why does swisseph require build tools like node-gyp?
The swisseph npm package is a native addon — it wraps the C library version of Swiss Ephemeris using Node.js N-API bindings. This means it compiles C code during npm install, which requires Python and a C compiler (build-essential on Linux, Xcode command-line tools on macOS, Visual Studio Build Tools on Windows). This is normal for high-performance native addons and is not a security risk.
What ephemeris data files does swisseph need?
Swiss Ephemeris uses pre-computed binary data files (.se1 extension) covering different time ranges. The swisseph npm package includes a basic set in node_modules/swisseph/ephe/. For dates outside ~3000 BCE to 3000 CE, you need additional files from the Swiss Ephemeris website. For astrology apps covering typical birth dates (1900-2100), the included files are sufficient.
What is the difference between Lahiri and Raman ayanamsa?
Ayanamsa is the offset between the tropical (Western) and sidereal (Vedic) zodiac. Lahiri ayanamsa (SE_SIDM_LAHIRI) is the official government-recognised ayanamsa in India and is used by ~90% of Vedic astrologers. Raman ayanamsa (SE_SIDM_RAMAN) was developed by B.V. Raman and differs from Lahiri by ~0.9 degrees. KP ayanamsa (used in Krishnamurti Paddhati) differs slightly more. For maximum compatibility with Indian astrology software, use Lahiri.
Can I use Swiss Ephemeris on Vercel or other serverless platforms?
Yes, but with caveats. Native Node.js addons require the compiled binary to match the platform architecture. On Vercel, you need to ensure the binary is built for Linux x64 (the Lambda runtime). Use @swisseph/swisseph or the swisseph package and test in a Docker container matching the Vercel runtime. Alternatively, use our API rather than running Swiss Ephemeris yourself — we handle all the infrastructure complexity.
Is Swiss Ephemeris accurate enough for professional Vedic astrology?
Yes. Swiss Ephemeris provides arc-second precision for planetary positions from 5400 BCE to 5400 CE. It is the same computation engine used by professional Vedic astrology software (Jagannatha Hora, Parashara's Light, Kala, etc.). The accuracy far exceeds what any astrological interpretation system can meaningfully use — the bottleneck is always interpretation, not computation.
Related Guides & Use Cases
Free Vedic API GuideDasha API IntegrationKundli API Use Case