# Changelog ## 3.2.1 * Trims the README preamble. The old one led with thanks to a package that has since been unpublished, and described this one as a slightly modified version of it, which stopped being true several releases ago. * Drops two dead links. `ephemeris-moshier` was unpublished from npm in May 2026 and `github.com/xErik/ephemeris-moshier` now 404s. * Keeps attribution, in one line rather than three paragraphs. The licence file is unmodified GPL-3.0 boilerplate with the author placeholders never filled in, and the ported sources carry no headers, so the README is the only place anyone is credited for work this is derived from. * Documentation only. ## 3.2.0 * Makes the calculation engine pluggable. The built in Moshier engine stays the default and nothing about a plain install changes: still no dependencies, still pure JavaScript, still the same numbers. * Adds adapters for two other engines, neither of them a dependency. Install `sweph` for Swiss Ephemeris, or `astronomy-engine` for a pure JavaScript MIT licensed alternative, then `ephemeris.use(...)`. Both are registered whichever is installed, so `ephemeris.backends()` reports what is usable here and why not when it is not. Note that Swiss Ephemeris is AGPL-3.0 or commercially licensed, which is stricter than this package and reaches hosted services. Installing it is a licensing decision, which is why it is not installed for you. * Every backend returns the whole catalogue, so the result shape never depends on the engine. A body a backend cannot produce comes back with the same keys, every value `null`, `available: false` and a reason that is often actionable, rather than throwing or being silently absent. * Adds `getBody`, for anything the catalogue does not name: numbered minor planets, fixed stars, or an engine's own identifiers. Takes one spec or a list, and unresolvable entries get the same template. * Adds `available`, `unavailableReason` and `backend` to every observed body, and `backend` to the result. Additive; no existing field changed name, type or value. * Adds `use`, `backend`, `backends` and `registerBackend`, so you can plug in your own engine. `src/backends/registry.js` documents the contract. * Fixes `sirius.apparentLongitudeDd`, which reported right ascension in radians while every other body reported degrees. It is now degrees, so 101.4549 where it used to say 1.7707, and it finally agrees with the `101 degrees 27' 17"` string printed beside it. The strings themselves are unchanged. Note that for a star the underlying quantity is still right ascension rather than ecliptic longitude, which is an older problem and is recorded as a known gap. * Documents how to obtain the Swiss Ephemeris data files, which the previous note assumed you already had. * Adds `npx ephemeris-fetch-ephe` and `ephemeris.fetchEphemeris()` to fetch them, about 2.1 MB. Downloads are pinned to an upstream commit and checked against a recorded SHA-256, so the same bytes arrive every time and a substituted or truncated file is refused rather than written. Running it again leaves good files alone. `fetchEphemeris({prompt: true})` asks first, naming what it will fetch, from where, and under what licence. It only asks when something is missing, and off a terminal it refuses rather than hanging or assuming yes. Pass `confirm` to answer from your own interface. Nothing downloads on install or during a calculation. `getAllPlanets` is synchronous, so asking mid calculation would mean blocking the event loop or making every signature async, and there is no terminal to ask on in CI or in a server anyway. A Swiss Ephemeris body that needs a missing file names the command in its `unavailableReason`. ## 3.1.1 * Restores the `3.0.1` changelog entry, which was lost when the lunar node work renamed that heading to `3.1.0` on the assumption the two would ship together. They did not: 3.0.1 was already released. The entry now sits with the version that actually carried it. * Adds a `2.1.0` entry, reconstructed from the published tarballs. That version has been on npm since July 2025 with nothing written about it. * Adds a test comparing the git tags, which the release workflow creates for every publish, against the changelog headings, so a released version cannot go undocumented again. * Documentation and tests only. ## 3.1.0 * Adds the lunar nodes as bodies: `rahu` and `ketu` for the mean nodes, and `trueRahu` and `trueKetu` for the osculating ones. They come back from `getAllPlanets` like anything else, and `getPlanet` accepts them. The mean node was already being computed inside the library and thrown away: `gplan` derives the moon's mean longitude and its mean distance from the node, and the node is the difference. It agrees with Meeus 47.7 to within 0.34 arcsec from 1700 to 2150. The true node comes from the orbital plane the moon is on at the instant, and lands within 0.37 arcsec of the moon's own longitude at a northward ecliptic crossing, which is the definition of the node. These are tropical longitudes of date, like everything else here. There is no ayanamsa, so `rahu` is not the sidereal Rahu until you subtract one. Nothing that already existed changed value. ## 3.0.1 * Moves the development and release instructions out of the README and into `CONTRIBUTING.md`, which is not in `files` and so does not ship. npm renders the README as the package page, so those sections were showing up there as a maintainer runbook in front of anyone looking at the library. * Moves the changelog into this file. The README keeps a pointer and the one note that matters before upgrading. npm has no changelog of its own, it only renders the README, so the release notes on GitHub are now the per-version view and this file is the full history. * Documentation only. ## 3.0.0 Breaking Changes - Please read carefully * Reports `is_retrograde` only for bodies that can actually be retrograde, which means the planets and the asteroids. The sun and the moon are never overtaken by the earth, so they cannot appear to move backwards; they now report `undefined` rather than a permanent `false`, matching what stars already did. Their `apparentLongitudeDdPerDay` is unaffected. Sampled over four centuries, solar motion never drops below 0.95 degrees a day and lunar motion never below 11.76, so there was never an answer to give. * Removes the unreachable iterative rise and set solver from `transit.js`, about 300 lines. It was never called from anywhere, in any commit, and the `kepler` call inside it was wrong from the initial 2018 commit, so it threw the moment it ran. Nothing changes for callers: the approximate times were always the ones being reported. Removing it also drops the last circular import in the package, `altaz` and `transit`, which made requiring `src/astronomy/moshier/transit` before the package entry point return a half built module. * Fixes rise, set and meridian times falling outside the day they belong to. They are measured from the start of the UT day holding the requested instant, but the instant itself is terrestrial time, and nothing wrapped an event landing either side of that boundary back into the day. So `approxSetUT` could report `hours: 43`, or a negative time. Querying at exactly midnight always tripped it, which is what `new Date('2026-04-18')` gives you. Across a year at six locations, 2179 of 7300 rise and set values were 24 hours out and 365 were negative; now none are. The times themselves were always right, and still agree with a bisection on the library's own elevation to within a few seconds. * Ships TypeScript definitions in `index.d.ts`. `getPlanet` is generic, so its result is narrowed to the body requested. * Modernises the source to ES2022 declarations. Every `var` became `let` or `const`, and `common.copy` takes rest parameters instead of reading `arguments`. The calculation itself is untouched and the output is byte identical, verified across five dates from 1900 to 2099 including the topocentric and transit values. * Requires Node 22 or newer. The calculation code is untouched and still produces byte identical results on older versions, but `engines` now states what is actually tested and supported. This matters because Yarn refuses to install a package whose `engines` it does not satisfy, where npm only warns. * Node 20 went end of life on 30 April 2026, which is what prompted this. Continuous integration now covers Node 22, 24 and 26, and the toolchain in `mise.toml` moves to Node 24, the active LTS. ## 2.3.0 * Fixes `is_retrograde`, which was previously wrong for most bodies. It compared two reductions of the same position vector rather than two positions, so the difference it measured was the change in obliquity over an hour, not the body's own motion. The flag was also inverted, missing for the sun and the moon, and dependent on the host machine's timezone. * Adds `apparentLongitudeDdPerDay`, the apparent motion in longitude * Adds `getBodyNames()`, and makes `getPlanet` throw on an unknown name * Migrates ESLint to the flat config required by ESLint 9, so `yarn run lint` works again * Replaces the placeholder test with real coverage of positions, retrograde windows and timezone independence ## 2.2.0 Feature added * Adds retrograde flag for planets ## 2.1.0 * Released 26th July 2025 * Drops the `postinstall` build step and the generated `build/` directory, so installing no longer runs a script * Drops the `path` dependency and adds ESLint and a mise config * Moves `custom.constant.js` under `src/` * Reconstructed after the fact from the published tarballs. It was tagged and published from a commit that is no longer in the repository history. ## 2.0.0 Breaking Changes - Please read carefully * Released 5th July 2020 * Removes dependency on Moment.js and uses JavaScript's default date object * Fixes names of a few variables as there were typos (Thanks [Erik](https://github.com/stenflo) for these changes) ## 1.0.0 * Released 30th June 2020 * updates test and fixes test