nrel-spa

A faithful TypeScript port of the NREL Solar Position Algorithm by Ibrahim Reda and Afshin Andreas (2008). Achieves ±0.0003° over the years −2000 to +6000.

Overview

nrel-spa is the solar position engine used internally by pray-calc. You can use it directly for any application that needs precise solar coordinates.

  • Based on NREL/TP-560-34302 (Reda & Andreas, 2008)
  • ±0.0003° accuracy
  • Outputs topocentric altitude, azimuth, right ascension, declination, hour angle
  • Full atmospheric refraction model (pressure + temperature)
  • TypeScript-first, ESM + CJS

GitHub: github.com/acamarata/nrel-spa

Installation

pnpm add nrel-spa

computeSolarPosition

computeSolarPosition(options: SolarPositionOptions): SolarPosition

Options

ParameterTypeRequiredDefaultDescription
dateDateYesDate and time (UTC)
latitudenumberYesDecimal degrees
longitudenumberYesDecimal degrees
elevationnumberNo0Metres above sea level
pressurenumberNo1013.25Millibars
temperaturenumberNo15Celsius
deltaTnumberNo69.18ΔT in seconds
slopenumberNo0Surface tilt angle (0 = horizontal)
azimuthRotationnumberNo0Surface azimuth rotation
atmosphericRefractionnumberNo0.5667Horizon refraction in degrees

Returns

FieldUnitDescription
topocentricAltitudedegreesSun's altitude above horizon (corrected for refraction)
topocentricAzimuthdegreesSun's azimuth clockwise from north
topocentricRightAscensionhoursEquatorial RA (topocentric)
topocentricDeclinationdegreesEquatorial declination (topocentric)
localHourAngledegreesHour angle from meridian
zenithAngledegreesAngle from zenith (90° − altitude)
geocentricSunDistanceAUEarth-Sun distance in astronomical units
equationOfTimeminutesΔT between solar noon and 12:00 local mean time

Example

import { computeSolarPosition } from 'nrel-spa'

const pos = computeSolarPosition({
  date: new Date('2025-06-21T09:00:00Z'),
  latitude: 21.4225,
  longitude: 39.8262,  // Mecca
  elevation: 270,
  pressure: 982,       // adjusted for 270m elevation
  temperature: 38,     // summer temperature in Mecca
})

console.log(`Altitude: ${pos.topocentricAltitude.toFixed(3)}°`)
console.log(`Azimuth: ${pos.topocentricAzimuth.toFixed(3)}°`)
console.log(`Equation of time: ${pos.equationOfTime.toFixed(2)} min`)

Accuracy

The algorithm achieves ±0.0003° (about 1 arcsecond) for the years −2000 to +6000. For comparison:

AlgorithmAccuracySource
NREL SPA±0.0003°Reda & Andreas (2008)
Jean Meeus (simplified)±0.01°Astronomical Algorithms (1991)
VSOP87 (full)±0.0001°Bretagnon & Francou (1988)
SunCalc.js~±0.1°Web-optimized approximation

For prayer times, ±0.0003° corresponds to a timing error of less than 1 second. The simplified Meeus method produces errors up to 30 seconds at equinoxes and near solstices at high latitudes.

Algorithm reference

The NREL SPA implements the following computational chain:

  1. Julian Day and Julian Ephemeris Day
  2. Heliocentric longitude and latitude (Fourier series, 2,500+ terms from VSOP87D)
  3. Geocentric longitude and latitude
  4. Nutation in longitude (Δψ) and obliquity (Δε)
  5. Aberration correction
  6. Apparent Sun longitude and right ascension
  7. Observer local hour angle
  8. Topocentric coordinates (parallax correction)
  9. Atmospheric refraction correction

Reference: Reda, I.; Andreas, A. (2008). Solar Position Algorithm for Solar Radiation Applications. NREL/TP-560-34302. Golden, CO: National Renewable Energy Laboratory.

Was this page helpful?