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

caelus

v0.10.0

Published

Astrological ephemeris engine. MIT, no AGPL, no ephemeris files. Checked against Swiss Ephemeris.

Readme

caelus

Astrological ephemeris engine. MIT, no Swiss Ephemeris code, no AGPL, no ephemeris files. 1:1 port of the Python reference, checked by golden fixtures.

Verification chain

  1. Python engine checked against Swiss Ephemeris 2.10 across 1900–2099: every planet ≤ 1″ (Sun–Saturn), Moon ≤ 2.5″, Chiron ≤ 1″, mean node ≤ 1″, true node ≤ 1′ vs SE's built-in ephemeris (≤ 1″ vs JPL DE431) (vs full DE431 files, 1850–2149), angles and Placidus cusps ≤ 3.2″ — all invisible at the arcminute display precision chart software uses.
  2. TypeScript port verified against Python golden fixtures: 3,218 checks, 0 failures, worst deviation 0.41 nano-arcseconds. The two implementations are numerically identical.

Regenerate fixtures any time from the Python side; any future TS change must keep this suite green.

Browser bundle weights (gzipped)

| component | size | |------------------------------------|---------| | engine code | 8 KB | | VSOP87 planets, embedded tier | 65 KB | | Moon series + nutation + Pluto | 2 KB | | Chiron (1850–2150) | 10 KB | | core total | ~85 KB | | VSOP micro tier (alt.) | 25 KB | | precise Moon 1920–2080 (lazy-load) | 729 KB |

The 85 KB core computes natal charts client-side — planets to sub-arcsecond, Moon to ~10″ via the analytic series. The 729 KB tier (1920–2080 JPL-fit Moon, 0.1″-class) lazy-loads when present; the engine switches automatically.

Usage

npm install caelus
import { Engine, fmtLon } from "caelus";
import { loadNodeData } from "caelus/node"; // Node only

// Node: filesystem loader
const engine = new Engine(loadNodeData("./data", "embedded", "full"));

// Browser/edge: bundled embedded dataset (~85 KB gz)
// import { embeddedData } from "caelus/data-embedded";
// const engine = new Engine(embeddedData);

// Browser: inject data yourself (bundle or fetch the JSON)
// const engine = new Engine({ vsop, nutation, moonMeeus, pluto, chiron, moonCheb });

const chart = engine.chart(1990, 6, 10, 14, 30, 0, 27.95, -82.46, "placidus");
console.log(fmtLon(chart.bodies.sun.lon));   // "19°27' Gemini"
console.log(chart.bodies.saturn.retrograde); // true
console.log(chart.angles, chart.cusps, chart.aspects);

// Single positions
engine.longitude("chiron", 2451545.0);
engine.position("mars", 2451545.0); // { lon, speed, retrograde, sign, signDeg }

Bodies: sun, moon, mercury…pluto, chiron, mean_node, true_node; on request: mean_lilith, true_lilith, ceres, pallas, juno, vesta, pholus, and the eight Hamburg-school Uranian bodies (cupido…poseidon) when their data packs are loaded. House systems: placidus, porphyry, equal, whole_sign, koch, regiomontanus, campanus, alcabitius, morinus, meridian, polich_page, vehlow (Placidus and Koch fall back to whole_sign above the polar circles). Event search: rise/set/meridian transits, zodiac crossings, lunar phases, stations (events.ts). Performance: ~2.4 ms per full chart (13 bodies × 3 evaluations + houses + aspects) single-threaded in Node 22 — ~420 charts/sec, faster in hot loops.

Layout

src/core.ts       timescales, VSOP87, Moon, Pluto, Chiron, nutation, frames
src/houses.ts     sidereal time, angles, four house systems
src/chart.ts      Engine class, aspects, formatting
src/node-loader.ts  fs convenience loader (core never touches fs)
data/             shared JSON coefficients (same files as Python package)
test/golden.test.ts  conformance suite vs Python fixtures

Porting notes (for future maintainers/agents)

  • mod() everywhere: JS % keeps the dividend's sign; Python's doesn't. Every angle reduction goes through mod().
  • Iteration order matters for bit-level agreement (e.g. the nutation table sums in reverse); keep orders identical to the Python reference.
  • All data is injected via EngineData — the core has zero I/O, zero deps, and runs identically in browser, edge runtime, or Node.

The caelus packages

  • caelus — this package
  • caelus-birth — local birth time + place → UT (charts take UT; use this)
  • caelus-wheel — React SVG chart wheel
  • caelus-mcp — MCP server, nine chart tools over stdio