npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@astronomy-bundle/solar-eclipse

v9.38.0

Published

Solar eclipse calculations for the astronomy bundle

Readme

Part of the Astronomy Bundle.

Solar Eclipse

The solarEclipse package provides solar eclipse calculations for any location on Earth. It uses Besselian Elements — pre-computed polynomial coefficients describing the Moon's shadow geometry — to determine eclipse type, contact times, magnitude, and obscuration at a specific geographic location and point in time.

Contents

Install

With npm: npm install @astronomy-bundle/solar-eclipse @astronomy-bundle/core
With yarn: yarn add @astronomy-bundle/solar-eclipse @astronomy-bundle/core
With pnpm: pnpm add @astronomy-bundle/solar-eclipse @astronomy-bundle/core

API Reference

Eclipse Catalogue

Two pre-computed eclipse catalogues are provided as separate subpath exports. Use them to list available eclipse dates, look up Besselian elements by date, and pass the result to SolarEclipse.createFromBesselianElements.

Both catalogue entrypoints export a Catalogue class with the same methods:

  • Catalogue.getAvailableEclipseDates(dateFrom?, dateTo?): returns sorted eclipse dates in YYYY-MM-DD format. The optional boundaries are inclusive.
  • Catalogue.getBesselianElements(date): returns the parsed Besselian elements for an eclipse date. It throws when the date is outside the catalogue range or when no eclipse exists on that date.

Standard catalogue (1900–2100)

Import from @astronomy-bundle/solar-eclipse/catalogue for the standard catalogue. It contains 454 eclipses, from 1900-05-28 to 2100-09-04, and is the default choice for modern dates. Requests outside the 1900–2100 catalogue range throw with a hint to use the full catalogue instead.

import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';

const availableDates = Catalogue.getAvailableEclipseDates('2026-01-01', '2026-12-31');
const elements = Catalogue.getBesselianElements('2026-08-12');
const eclipse = SolarEclipse.createFromBesselianElements(elements);

Full catalogue (−1999–3000)

⚠️ Warning: The full catalogue is about 1 MB uncompressed. Avoid importing it in browser bundles or size-sensitive environments unless necessary.

For eclipses outside the standard range, import from @astronomy-bundle/solar-eclipse/catalogue-full. It contains 11,898 eclipses, from -1999-06-12 to 3000-10-19, while leaving the standard catalogue entrypoint unchanged. Negative years use signed astronomical year numbering.

import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue-full';

const availableDates = Catalogue.getAvailableEclipseDates(); // All dates from -1999-06-12 to 3000-10-19
const elements = Catalogue.getBesselianElements('-0500-03-14');
const eclipse = SolarEclipse.createFromBesselianElements(elements);

SolarEclipse

SolarEclipse represents a solar eclipse event and provides global eclipse properties such as type, greatest eclipse location and time, and peak magnitude. It is the primary entry point for eclipse calculations.

Example: Total solar eclipse on 2 July 2019

import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';

const elements = Catalogue.getBesselianElements('2019-07-02');
const eclipse = SolarEclipse.createFromBesselianElements(elements);

Create a SolarEclipse object

Description: The createFromBesselianElements static method creates a SolarEclipse instance from a BesselianElements object. This is the only static constructor on SolarEclipse. Use the built-in Catalogue entrypoints for date-based lookup, or pass custom pre-computed Besselian elements.

import {SolarEclipse, parseBesselianElements} from '@astronomy-bundle/solar-eclipse';

// ASE 2016-09-01
const elements = parseBesselianElements([
    2457632.88058,  9.0,  -3.0,  3.0,  0,  0,
    -0.16139600,    0.50406349,  -0.00002140,  -0.00000631,
    -0.29965001,   -0.14815210,  -0.00002580,   0.00000178,
     8.06330013,   -0.01480200,  -0.00000200,
     315.03155518,  15.00454044,  0.00000000,
     0.55792803,    0.00011150,  -0.00001050,
     0.01173100,    0.00011100,  -0.00001040,
     0.00463390,    0.00461090,  135
]);

const eclipse = SolarEclipse.createFromBesselianElements(elements);

Eclipse type

Description: Returns the global eclipse type as a SolarEclipseType value. Possible values are 'partial', 'total', 'annular', and 'hybrid'.

const type = eclipse.getType();

The result of the calculation should be: total


Saros series

Description: Returns the Saros series number the eclipse belongs to. Eclipses of the same Saros series recur roughly every 18 years, 11 days, and 8 hours.

const saros = eclipse.getSaros();

The result of the calculation should be: 127


Location of greatest eclipse

Description: Returns the geographic coordinates {lat, lon} (in decimal degrees) of the point on Earth's surface where the eclipse is greatest — i.e., where the Moon's shadow axis passes closest to the centre of the Earth.

const {lat, lon} = eclipse.getLocationOfGreatestEclipse();

The result of the calculation should be:
lat: -17.388965
lon: -108.998853


Time of greatest eclipse

Description: Returns a TimeOfInterest representing the moment of greatest eclipse in Terrestrial Time (TT).

const toi = eclipse.getTimeOfGreatestEclipse();
const {year, month, day, hour, min, sec} = toi.getTime();

The result of the calculation should be: 2019-07-02 19:22:58


Gamma

Description: Returns gamma — the least distance of the Moon's shadow axis from the centre of the Earth at greatest eclipse, measured in units of Earth's equatorial radius. It is positive when the axis passes north of the centre and negative when it passes south. A value near 0 indicates a central eclipse crossing near the equator, while a magnitude above roughly 1 indicates a partial eclipse whose axis misses the Earth.

const gamma = eclipse.getGamma();

The result of the calculation should be: -0.646562


Maximum magnitude

Description: Returns the eclipse magnitude at greatest eclipse — the fraction of the Sun's diameter covered by the Moon at the point and moment of greatest eclipse. Values above 1 indicate a total eclipse.

const magnitude = eclipse.getMaxMagnitude();

The result of the calculation should be: 1.022966


Maximum Moon/Sun ratio

Description: Returns the ratio of the apparent angular diameter of the Moon to that of the Sun at the moment of greatest eclipse. A ratio greater than 1 means totality is possible; less than 1 means an annular eclipse is possible.

const ratio = eclipse.getMaxMoonSunRatio();

The result of the calculation should be: 1.045932


Maximum obscuration

Description: Returns the fraction of the Sun's area obscured by the Moon at greatest eclipse, as a value between 0 and 1. Returns 1 for total eclipses.

const obscuration = eclipse.getMaxObscuration();

The result of the calculation should be: 1


Umbra path width

Description: Returns the width of the path of totality (or annularity) at greatest eclipse, in meters — the width of the band swept by the Moon's umbra (or antumbra) across Earth's surface. The band widens as the Sun sinks toward the horizon. Returns 0 for partial eclipses, where the shadow axis never reaches the ground.

const pathWidthMeters = eclipse.getUmbraPathWidth();

The result of the calculation should be: 200867.2


Maximum duration

Description: Returns the total duration of the eclipse in seconds at the point of greatest eclipse, measured from first contact (C1) to last contact (C4).

const durationSeconds = eclipse.getMaxDuration();

The result of the calculation should be: 11847.3


Maximum central duration

Description: Returns the duration of the central phase (totality or annularity) in seconds at the point of greatest eclipse, measured from second contact (C2) to third contact (C3).

const centralDurationSeconds = eclipse.getMaxCentralDuration();

The result of the calculation should be: 272.8


Shadow geometry

Description: The following methods trace the Moon's shadow across Earth's surface: the central line, the umbra (path of totality/annularity), the penumbra (region of partial visibility), and the sunrise/sunset boundary loops. They all accept the same optional ShadowPathOptions object:

  • stepsInSeconds (default: 10) — the time resolution in seconds between sampled points; smaller values produce a denser, more precise path. Ignored by the sunrise/sunset boundary polygons, which use a fixed internal resolution.
  • refraction (default: false) — the horizon convention used for the endpoints. When false, the geometric horizon (Sun altitude 0°) is used. When true, the standard rise/set horizon (−50′, i.e. 34′ atmospheric refraction plus the Sun's 16′ semidiameter) is used, so the path reaches slightly further to where the Sun is still visible at the horizon.
Central line

Returns the path of the central eclipse (totality or annularity) as an array of {lat, lon} coordinate objects in decimal degrees. Points are computed by stepping through the eclipse duration and projecting the Moon's shadow axis onto Earth's surface, ending exactly where the axis crosses the horizon. Points where the shadow axis misses Earth are omitted.

const path = eclipse.getCentralLine();
// [{lat: ..., lon: ...}, ...]

// Higher resolution (1-second steps)
const densePath = eclipse.getCentralLine({stepsInSeconds: 1});
Umbra path polygon

Returns the path of totality (or annularity) as a single closed polygon — the region ever covered by the Moon's umbra while the Sun stands above the horizon, matching the umbral shading on eclipse maps. The result is an array of {lat, lon} coordinate objects in decimal degrees whose first and last points are identical, so the ring is closed. Returns an empty array for a purely partial eclipse, where the umbra never touches the surface.

const polygon = eclipse.getUmbraPathPolygon();
// [{lat: ..., lon: ...}, ..., {lat: ..., lon: ...}] — first point equals last

The closed ring is ready to draw on a map or to run a point-in-polygon test against to check whether a location lies within the path of totality.

Penumbra path polygon

Returns the region of the partial eclipse as a single closed polygon — the area where any part of the eclipse is visible (the Moon's penumbra touches the ground) while the Sun stands above the horizon. The result is an array of {lat, lon} coordinate objects in decimal degrees whose first and last points are identical, so the ring is closed.

const polygon = eclipse.getPenumbraPathPolygon();
// [{lat: ..., lon: ...}, ..., {lat: ..., lon: ...}] — first point equals last
Sunrise / sunset boundary polygons

Return the rise/set boundary curves shown on eclipse maps — the closed loops enclosing the region where the eclipse is already in progress as the Sun rises or sets. getSunriseBoundaryPolygon traces the sunrise side, getSunsetBoundaryPolygon the sunset side. Each result is an array of {lat, lon} coordinate objects in decimal degrees whose first and last points are identical, so the ring is closed. Only the refraction option applies here; stepsInSeconds is ignored. For an eclipse whose penumbra never fully leaves the day/night terminator both halves form a single loop, which is returned on one side while the other side is an empty array.

const sunrisePolygon = eclipse.getSunriseBoundaryPolygon();
const sunsetPolygon = eclipse.getSunsetBoundaryPolygon();
// [{lat: ..., lon: ...}, ..., {lat: ..., lon: ...}] — first point equals last

Local eclipse for an observer

Description: Returns a LocalSolarEclipse instance for a specific observer location. Use this to calculate contact times, local eclipse type, magnitude, and obscuration as seen from that location.

import {Location} from '@astronomy-bundle/core';

const location = Location.create(21.52854, 39.14387, 6);
const localEclipse = eclipse.getLocalEclipse(location);

LocalSolarEclipse (Eclipse + Location)

LocalSolarEclipse represents a solar eclipse as seen from a specific observer location. It provides contact times, local eclipse type, magnitude, obscuration, and duration for that observer.

Example: Annular solar eclipse on 1 September 2016, observer on Réunion (−21.32947°N, 55.45174°E, 43 m)

import {Location} from '@astronomy-bundle/core';
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';

const location = Location.create(-21.32947, 55.45174, 43);
const elements = Catalogue.getBesselianElements('2016-09-01');

const localEclipse = SolarEclipse
    .createFromBesselianElements(elements)
    .getLocalEclipse(location);

Local eclipse type

Description: Returns the local eclipse type as a LocalSolarEclipseType value. Possible values are 'partial', 'total', and 'annular'.

const type = localEclipse.getType();

The result of the calculation should be: annular


Contact times as τ offsets

Description: Returns the contact times as dimensionless time offsets (τ) relative to t0 in the Besselian elements. c1 and c4 are always present; c2 and c3 are only set for central (total or annular) eclipses and are null for partial eclipses. max is the moment of greatest eclipse at this location.

const contacts = localEclipse.getContactTaus();

const {c1, c2, max, c3, c4} = contacts;

The result of the calculation should be:
c1: -0.587742
c2: 1.161350
max: 1.185225
c3: 1.20914
c4: 2.730088


Contact times

Description: Returns the contact times as TimeOfInterest objects in Terrestrial Time (TT). c1 is first external contact, c2 second contact (start of central phase), max is greatest eclipse, c3 third contact (end of central phase), and c4 last external contact. c2 and c3 are null for partial eclipses.

const contacts = localEclipse.getContactTimes();

const {year: y1, month: mo1, day: d1, hour: h1, min: m1, sec: s1} = contacts.c1.getTime();
const {year: y2, month: mo2, day: d2, hour: h2, min: m2, sec: s2} = contacts.c2.getTime();
const {year: ym, month: mom, day: dm, hour: hm, min: mm, sec: sm} = contacts.max.getTime();
const {year: y3, month: mo3, day: d3, hour: h3, min: m3, sec: s3} = contacts.c3.getTime();
const {year: y4, month: mo4, day: d4, hour: h4, min: m4, sec: s4} = contacts.c4.getTime();

The result of the calculation should be:
c1: 2016-09-01 08:23:35
c2: 2016-09-01 10:08:32
max: 2016-09-01 10:09:58
c3: 2016-09-01 10:11:24
c4: 2016-09-01 11:42:39


Maximum magnitude

Description: Returns the eclipse magnitude at greatest local eclipse — the fraction of the Sun's diameter covered by the Moon at the observer's location. Values below 1 indicate a partial or annular eclipse; values above 1 indicate totality.

const magnitude = localEclipse.getMaxMagnitude();

The result of the calculation should be: 0.980734


Maximum Moon/Sun ratio

Description: Returns the ratio of the apparent angular diameter of the Moon to that of the Sun at the moment of greatest local eclipse. A ratio below 1 means an annular eclipse is possible; above 1 means totality is possible.

const ratio = localEclipse.getMaxMoonSunRatio();

The result of the calculation should be: 0.970421


Maximum obscuration

Description: Returns the fraction of the Sun's area obscured by the Moon at greatest local eclipse, as a value between 0 and 1. Returns 1 for total eclipses; less than 1 for annular and partial eclipses.

const obscuration = localEclipse.getMaxObscuration();

The result of the calculation should be: 0.941717


Umbra path width

Description: Returns the width of the path of totality (or annularity) at the observer's location, in meters — the width of the band swept by the Moon's umbra (or antumbra) as it passes the observer at greatest local eclipse. The band widens as the Sun sinks toward the horizon, so the value can differ from the eclipse's maximum width. Returns 0 when the observer sees only a partial eclipse.

const pathWidthMeters = localEclipse.getUmbraPathWidth();

The result of the calculation should be: 108317.1


Duration

Description: Returns the total duration of the eclipse in seconds at the observer's location, measured from first contact (C1) to last contact (C4).

const durationSeconds = localEclipse.getDuration();

The result of the calculation should be: 11944.2


Central duration

Description: Returns the duration of the central phase (totality or annularity) in seconds at the observer's location, measured from second contact (C2) to third contact (C3). Returns 0 for partial eclipses.

const centralDurationSeconds = localEclipse.getCentralDuration();

The result of the calculation should be: 172.0


Circumstances at a given time

Description: Returns a LocalEclipseCircumstances instance for a specific moment in time at the observer's location. Use this to query eclipse state (type, magnitude, obscuration) at any point during the eclipse.

import {TimeOfInterest} from '@astronomy-bundle/core';

const toi = TimeOfInterest.fromTime(2016, 9, 1, 10, 9, 58);
const circumstances = localEclipse.getCircumstances(toi);

LocalEclipseCircumstances (Eclipse + Location + Time)

LocalEclipseCircumstances represents the eclipse conditions at a specific geographic location and moment in time. It requires a BesselianElements object (describing the eclipse), a Location, and a TimeOfInterest.

Example: Total solar eclipse on 2 August 2027, observer in Jeddah, Saudi Arabia (21.52854°N, 39.14387°E, 6 m)

import {TimeOfInterest, Location} from '@astronomy-bundle/core';
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';

const location = Location.create(21.52854, 39.14387, 6);
const toiPartial = TimeOfInterest.fromTime(2027, 8, 2, 10, 1, 5);
const toiTotal   = TimeOfInterest.fromTime(2027, 8, 2, 10, 23, 13);
const elements = Catalogue.getBesselianElements('2027-08-02');

const localEclipse = SolarEclipse
    .createFromBesselianElements(elements)
    .getLocalEclipse(location);

// Local circumstances during partial phase in Jeddah
const circumstancesPartial = localEclipse.getCircumstances(toiPartial);

// Local circumstances during total phase in Jeddah
const circumstancesTotal = localEclipse.getCircumstances(toiTotal);

Eclipse type at a given moment

Description: Returns the eclipse type at the observer's location for the given moment. Possible values are 'none', 'partial', 'total', and 'annular'. Returns 'none' before the eclipse has started or after it has ended.

Example: Get eclipse type during partial and total phases

const typePartial = circumstancesPartial.getEclipseType();
const typeTotal   = circumstancesTotal.getEclipseType();

The result of the calculation should be:
During partial phase: partial
During total phase: total


Eclipse in progress

Description: Returns true if any eclipse is in progress at the given moment (partial, total, or annular phase). Returns false before first contact and after last contact.

Example: Check whether the eclipse is in progress

const inEclipsePartial = circumstancesPartial.isInEclipse();
const inEclipseTotal   = circumstancesTotal.isInEclipse();

The result of the calculation should be:
During partial phase: true
During total phase: true


Central eclipse in progress

Description: Returns true only during the central phase — totality or annularity. Returns false during the partial phase, before first contact, and after last contact.

Example: Check whether totality (or annularity) is in progress

const inCentralPartial = circumstancesPartial.isInCentralEclipse();
const inCentralTotal   = circumstancesTotal.isInCentralEclipse();

The result of the calculation should be:
During partial phase: false
During total phase: true


Umbra shadow outline

Description: Returns the instantaneous outline of the Moon's umbra — or the antumbra, for annular eclipses — projected onto Earth's surface at this moment: the actual shadow footprint at that instant, as opposed to the full swept band returned by getUmbraPathPolygon. The result is an array of {lat, lon} coordinate objects in decimal degrees tracing the shadow edge, ready to draw on a map. Returns null when the observer is not within the central shadow at this moment, so any partial-phase or pre/post-eclipse moment yields no footprint.

It accepts the same refraction option as the shadow geometry methods:

  • refraction (default: false) — the horizon convention used to clip the footprint. When false, the geometric horizon (Sun altitude 0°) is used. When true, the standard rise/set horizon (−50′) is used, so a footprint touching the horizon reaches slightly further to where the Sun is still visible. It only makes a difference when the shadow is near the horizon; for a high Sun both conventions give the same outline.

Example: Get the umbra footprint during the total and partial phases in Jeddah

const outlineTotal   = circumstancesTotal.getUmbraShadowOutline();
const outlinePartial = circumstancesPartial.getUmbraShadowOutline();
// outlineTotal:   [{lat: ..., lon: ...}, ...] — traces the umbra footprint enclosing the observer
// outlinePartial: null — the observer is outside the umbra during the partial phase

// Refraction-corrected horizon
const outlineRefracted = circumstancesTotal.getUmbraShadowOutline({refraction: true});

Magnitude

Description: Returns the eclipse magnitude — the fraction of the Sun's diameter covered by the Moon. During the partial phase the value is between 0 and 1; it exceeds 1 during totality and is negative before the eclipse begins.

Example: Get magnitude during partial and total phases

const magnitudePartial = circumstancesPartial.getMagnitude();
const magnitudeTotal   = circumstancesTotal.getMagnitude();

The result of the calculation should be:
During partial phase: 0.737313
During total phase: 1.011516


Obscuration

Description: Returns the fraction of the Sun's area obscured by the Moon, as a value between 0 and 1. Unlike magnitude, this is an area-based measure and never exceeds 1. Returns 0 when no eclipse is in progress and 1 during totality.

Example: Get obscuration during partial and total phases

const obscurationPartial = circumstancesPartial.getObscuration();
const obscurationTotal   = circumstancesTotal.getObscuration();

The result of the calculation should be:
During partial phase: 0.684313
During total phase: 1


Geometric topocentric horizontal coordinates

Description: Returns the geometric topocentric horizontal coordinates of the Sun for the observer's location and given moment. The result contains azimuth and altitude in degrees, plus radiusVector set to 0.

Example: Get geometric Sun coordinates during totality

const horizontal = circumstancesTotal.getTopocentricHorizontalCoordinates();

The result of the calculation should be:
Azimuth: 255.664319°
Geometric altitude: 76.861319°


Apparent topocentric horizontal coordinates

Description: Returns the apparent topocentric horizontal coordinates of the Sun for the observer's location and given moment. The altitude includes atmospheric refraction correction; azimuth and radiusVector are unchanged from the geometric coordinates.

Example: Get refraction-corrected Sun coordinates during totality

const apparentHorizontal = circumstancesTotal.getApparentTopocentricHorizontalCoordinates();

The result of the calculation should be:
Azimuth: 255.664319°
Apparent altitude (with refraction): 76.865248°