Guides

Recipes

Query the sky with when()

The engine answers "where is the body?"; when() answers "when is the configuration true?" over a time range. Predicates combine with allOf, anyOf, and notOf.

when.ts
import { when, allOf, aspect, inSign, notRetrograde, julianDay } from "caelus";

const start = julianDay(2026, 1, 1);
const end = julianDay(2028, 1, 1);

const intervals = when(
engine,
allOf(
  aspect("saturn", "square", 95.4), // within orb of an exact square to a longitude
  notRetrograde("mercury"),
  inSign("venus", "Taurus"),
),
start, end,
);

With the Node data tier, search rise/set, lunar phases, stations, and zodiac crossings:

events.ts
import { lunarPhases, stations, julianDay } from "caelus";

const jd = julianDay(2026, 1, 1);
lunarPhases(engine, jd, jd + 90);   // [[jd, "full"], ...]
stations(engine, "mercury", jd, jd + 365);

Match a configuration

A chart reduces to a feature vector, so you can score how closely the sky at any instant resembles a target form, and search a range for the best match.

match.ts
import { chartFeatures, searchConfigurations, julianDay } from "caelus";

// the feature vector of a target moment (say, a natal chart)
const target = chartFeatures(engine, julianDay(1990, 6, 14, 12, 0));

// rank the next year by resemblance to that configuration, best first
const matches = searchConfigurations(engine, target, {
start: julianDay(2026, 1, 1),
end: julianDay(2027, 1, 1),
step: 1,        // days
limit: 5,
});

Compile a form from constraints

The compiler inverts (time, place) -> chart: give it geometric constraints and it finds the body longitudes that best satisfy them, flagging a form as impossible when even the best fit falls short.

compile.ts
import { compileForm } from "caelus";

const form = compileForm([
{ kind: "aspect", a: "sun", b: "moon", angle: 120 }, // a trine
{ kind: "sign", body: "mars", sign: 7 },             // Scorpio (0-indexed)
{ kind: "degree", body: "venus", degree: 15 },
]);

form.longitudes;  // { sun, moon, mars, venus }
form.residual;    // total weighted constraint loss, in degrees
form.impossible;  // true when the worst constraint cannot be met

Render a chart wheel

caelus-wheel takes the chart object (or an MCP payload) and renders SSR-safe SVG.

Wheel.tsx
import { ChartWheel } from "caelus-wheel";

<ChartWheel chart={chart} size={520} showAspects />;

See the Playground for live wheels and the API Reference for the full surface.