Guides

Data Tiers

The engine is given its ephemeris data explicitly. Two suppliers ship with the package: the embedded dataset for the browser and edge, and the Node loader for the extended packs. The hosted REST demo and MCP server build on these two.

What runs where

CapabilityEmbedded (browser, edge)Node loaderREST /api/chartMCP (caelus-mcp)
Core bodies (Sun–Pluto, Chiron, nodes)
Houses (12 systems), angles, aspectsPlacidus
Tropical + 7 sidereal ayanamsastropical
Derived charts (returns, progressions, …)transits, synastry
Extended bodies (asteroids, Uranian points)
Fixed stars (318-star catalog)
Event search (rise/set, crossings, phases, stations)
Eclipses (solar, lunar)
Data on disknone (bundled)JSON packs (precise Moon ~3.1 MB + catalogs)none (edge)JSON packs (Node)
Date range1800–2149¹1800–2149¹1800–21491800–2149¹
Accuracyper body, see Validationper body, see Validationper bodyper body

Embedded (browser, edge)

caelus/data-embedded bundles a compact dataset: the eight planets, the Moon, Pluto, Chiron, the nodes, and the HYG fixed-star catalog (~13 KB gzipped of the ~98 KB total), with the core house systems and aspects. This is what runs client-side and on edge runtimes, with no files on disk.

embedded.ts
import { Engine } from "caelus";
import { embeddedData } from "caelus/data-embedded";

const engine = new Engine(embeddedData);

Node loader (extended)

loadNodeData reads the larger JSON packs from disk: higher-precision VSOP tiers, the precise Moon pack, a wide-range Pluto pack (a Chebyshev fit to the JPL Horizons barycenter that supersedes the embedded Meeus series and holds across 1850–2150), the asteroids and Uranian points. Fixed stars ship in embedded too; the Node loader reads the same catalog from disk when you load extended packs. Use the Node tier when you need extended bodies or event search.

node.ts
import { Engine } from "caelus";
import { loadNodeData } from "caelus/node";

const engine = new Engine(loadNodeData());
const star = engine.fixedStar("Aldebaran", jd);

Turbo (bulk longitude scans)

For century-scale work that evaluates a longitude tens of thousands of times (a long transit scan, a returns sweep), the Turbo tier trades generality for speed. A turbo pack is a segmented Chebyshev representation of the engine's own apparent longitude, fit to the engine itself, so one evaluation is a couple of dozen multiply-adds. The pack is data you mint for your range and bodies; the runtime evaluator does no I/O and needs no engine.

turbo.ts
import { Turbo } from "caelus";

// pack: a TurboPack you minted for your range/bodies (python/fit_turbo.py).
const turbo = new Turbo(pack);
turbo.has("mars");            // is this body in the pack?
turbo.longitude("mars", jd);  // apparent longitude (degrees), within [jd0, jd1]

Bundle sizes

The choice between client-side and server-side computation comes down to one number: the embedded dataset. The engine code tree-shakes small (a chart-only import drops event search, eclipses, the query and turbo tiers, and the derived and electional layers); the weight a browser pays is the coefficient data it bundles.

What you shipApprox. gzippedNotes
Embedded dataset (caelus/data-embedded)~97 KBplanets, Moon series, Pluto, Chiron, nutation, fixed-star catalog; full client-side charts
Precise Moon tier (caelus/node)~700 KB~3.1 MB on disk; lazy, never in the initial bundle
caelus-wheela few KBReact is a peer dependency, not bundled
caelus-birthsmall code, plus IANA timezone datathe timezone data is the weight, not the resolver
caelus-mcpserver-sidenot a browser bundle

So: ship caelus + caelus/data-embedded for full charts in the browser (the data dominates, the code is a small addition on top of your app), or compute server-side through the REST endpoint or the MCP server and ship only caelus-wheel to render the result.

Start building

Quickstart →