caelus
v0.24.1
Published
Clean-room TypeScript astrology computation: ephemeris, charts, events, timing techniques, Vedic methods, and citable chart facts. MIT, no AGPL or ephemeris files.
Maintainers
Readme
caelus
Clean-room TypeScript astrology computation: ephemeris, charts, events, hellenistic timing techniques, Vedic methods, citable chart facts, sky-view image-prompt frames, and synthetic ephemeris for imaginary bodies. MIT, no Swiss Ephemeris code, no AGPL, no ephemeris files. 1:1 port of the Python reference, checked by golden fixtures.
Verification chain
- Python engine checked against Swiss Ephemeris 2.10 across 1850–2150: 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.
- TypeScript port verified against Python golden fixtures: 3,397 checks, 0 failures, worst deviation 0.61 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 | | Fixed-star catalog (HYG) | 13 KB | | core total | ~97 KB | | VSOP micro tier (alt.) | 25 KB | | precise Moon 1920–2080 (lazy-load) | 729 KB |
The ~97 KB core computes natal charts client-side — planets to sub-arcsecond, Moon to ~10″ via the analytic series, fixed stars from the bundled HYG catalog. The 729 KB tier (1920–2080 JPL-fit Moon, 0.1″-class) lazy-loads when present; the engine switches automatically.
Usage
npm install caelusimport { 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 (~97 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 fixturesPorting notes (for future maintainers/agents)
mod()everywhere: JS%keeps the dividend's sign; Python's doesn't. Every angle reduction goes throughmod().- 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, thirty-five chart tools over stdio
