Skip to content

Astrology

WebAssembly requirement

Most functions in this module use the Swiss Ephemeris compiled to WebAssembly. See the integration guide before using them.

Functions that are pure math (no WASM) are noted in each section.


1. Birth Charts

import { getBirthChart, HouseSystem } from 'kaabalah/astrology';

getBirthChart(options): Promise<BirthChart>

Calculates a full natal chart. Timezone is auto-detected from latitude/longitude by default.

const chart = await getBirthChart({
date: { year: 1990, month: 6, day: 15, hour: 14, minute: 30 },
latitude: 48.856,
longitude: 2.352,
houseSystem: HouseSystem.PLACIDUS, // optional, defaults to PLACIDUS
timeZoneSettings: { autoTimeZone: true }, // default — or { timeZone: 'America/Paris' }
});
chart.planets.sun.zodiacPosition.sign // "Gemini"
chart.planets.sun.zodiacPosition.house // 10
chart.houses.ascendant.sign // "Virgo"
chart.houses.mc.sign // "Gemini"
chart.nodes.parsfortunae.zodiacPosition.sign // Part of Fortune
chart.aspects // AspectEdge[]
chart.sect // "diurnal" | "nocturnal"
chart.dateUtc // Date (UTC)

BirthChartOptions

FieldTypeDescription
dateDate | LocalDateTimePartsLocal civil date-time. Use LocalDateTimeParts ({ year, month, day, hour?, minute?, second? }) to avoid timezone ambiguity.
latitudenumber−90 to 90
longitudenumber−180 to 180
houseSystemHouseSystemOptional. Defaults to PLACIDUS.
timeZoneSettingsTimeZoneOptionsOptional. Defaults to { autoTimeZone: true }.

BirthChart return type

FieldTypeDescription
dateUtcDateChart moment in UTC.
planetsRecord<string, HydratedPlanet>Keyed by lowercase planet name (e.g. "sun", "moon", "true node").
nodesRecord<string, HydratedNode>Currently contains parsfortunae (Part of Fortune).
housesobjectContains ascendant, mc, dc, ic, houses[], and optional ascmc auxiliary points.
aspectsAspectEdge[]All intra-chart aspects including Ascendant and MC.
sect"diurnal" | "nocturnal"Sun above horizon = diurnal.

ZodiacPosition (used throughout):

{
sign: string; // e.g. "Scorpio"
decimalDegrees: number; // 0–30 within sign
traditionalFormat: string; // "9°48'"
decimal: string; // "9.80°"
longitude: number; // 0–360
house: number; // 1–12
}

House systems

ConstantDescription
HouseSystem.PLACIDUSDefault, most widely used
HouseSystem.WHOLE_SIGNRequired for profections and firdaria
HouseSystem.KOCHKoch
HouseSystem.EQUALEqual from Ascendant
HouseSystem.REGIOMONTANUSRegiomontanus
HouseSystem.CAMPANUSCampanus
HouseSystem.PORPHYRIUSPorphyry
HouseSystem.MORINUSMorinus
HouseSystem.MERIDIANMeridian
HouseSystem.KRUSINSKIKrusinski
HouseSystem.ALCABITIUSAlcabitius

2. Synastry

import { getSynastryChart } from 'kaabalah/astrology';

getSynastryChart(options): Promise<SynastryChart>

Calculates two birth charts and computes all cross-chart aspects (every planet/angle in chart A against every planet/angle in chart B).

const synastry = await getSynastryChart({
chartA: { date: new Date('1990-06-15'), latitude: 48.856, longitude: 2.352 },
chartB: { date: new Date('1992-03-21'), latitude: 51.5, longitude: -0.12 },
aspectSpecs: DEFAULT_ASPECT_SPECS, // optional override
});
synastry.chartA // BirthChart
synastry.chartB // BirthChart
synastry.aspects // AspectEdge[] — cross-chart aspects

SynastryChartOptions extends TwoChartOptions:

FieldTypeDescription
chartABirthChartOptionsFirst person’s chart options.
chartBBirthChartOptionsSecond person’s chart options.
aspectSpecsAspectSpec[]Optional. Overrides default aspect orbs.

3. Composite Charts

import { getCompositeChart } from 'kaabalah/astrology';

getCompositeChart(options): Promise<CompositeChart>

Calculates a midpoint composite chart from two birth charts. Planets and house cusps are computed as the shorter-arc midpoint of the corresponding points in each chart.

const composite = await getCompositeChart({
chartA: { date: new Date('1990-06-15'), latitude: 48.856, longitude: 2.352 },
chartB: { date: new Date('1992-03-21'), latitude: 51.5, longitude: -0.12 },
});
composite.chartA // BirthChart
composite.chartB // BirthChart
composite.compositePlanets // Record<string, { name, longitude, zodiacPosition }>
composite.compositeHouses // ZodiacPosition[]
composite.aspects // AspectEdge[] — aspects within composite chart

4. Transits

import { getTransitChart, getTransitRange } from 'kaabalah/astrology';

getTransitChart(options): Promise<TransitChart>

Places current (or any date’s) transiting planets against a natal chart. Transit planets are placed into natal houses.

const transit = await getTransitChart({
natal: { date: new Date('1990-06-15'), latitude: 48.856, longitude: 2.352 },
transitDate: new Date('2026-04-22'),
maxOrb: 3,
aspectFilter: ['conjunction', 'square', 'opposition'],
transitPlanets: ['saturn', 'pluto'],
natalPlanets: ['sun', 'moon', 'ascendant', 'mc'],
transitLatitude: 48.856, // optional, defaults to natal location
transitLongitude: 2.352,
});
transit.natalChart // BirthChart
transit.transitDateUtc // Date
transit.transitPlanets // Record<string, TransitPlanet>
transit.aspects // TransitAspectEdge[]

TransitChartOptions

FieldTypeDefaultDescription
natalBirthChartOptionsrequiredNatal chart options.
transitDateDaterequiredThe transit moment.
transitLatitudenumbernatal latitudeOverride transit location.
transitLongitudenumbernatal longitudeOverride transit location.
aspectSpecsAspectSpec[]DEFAULT_ASPECT_SPECSOverride orbs.
maxOrbnumberFilter to aspects tighter than this orb.
aspectFilterAspectName[]Keep only these aspect types.
transitPlanetsstring[]allLowercase planet names to include as transit points.
natalPlanetsstring[]allLowercase natal points to use as targets (includes "ascendant", "mc").

TransitAspectEdge (extends AspectEdge):

FieldTypeDescription
applyingbooleanTrue when the orb is decreasing.
retrogradebooleanTrue when the transit planet is moving retrograde.
category"slow" | "fast"Slow: Saturn, Jupiter, Uranus, Neptune, Pluto, Chiron, Nodes.

getTransitRange(options): Promise<TransitRangeResult>

Scans a date range and returns exact aspect perfection dates found via binary search (minute precision). The Moon and other fast planets auto-reduce the scan step to 0.25 days to avoid missed perfections.

const range = await getTransitRange({
natal: { date: new Date('1990-06-15'), latitude: 48.856, longitude: 2.352 },
from: new Date('2026-04-01'),
to: new Date('2026-06-01'),
stepDays: 1,
maxOrb: 2,
transitPlanets: ['saturn', 'neptune'],
});
range.natalChart // BirthChart
range.from // Date
range.to // Date
range.perfections // AspectPerfection[]

AspectPerfection:

FieldTypeDescription
transitPlanetstringName of transiting planet.
natalPlanetstringName of natal point.
aspectAspectNameAspect type.
exactDateDateMoment of closest approach.
exactOrbnumberOrb at perfection (degrees).
retrogradebooleanWhether transit planet was retrograde at perfection.
category"slow" | "fast"Planet speed category.

5. Solar Returns

import { getSolarReturnChart } from 'kaabalah/astrology';

getSolarReturnChart(options): Promise<SolarReturnChart>

Finds the exact UTC moment when the transiting Sun returns to its natal longitude in the specified year (binary search, minute precision), then casts a full chart at that moment.

const sr = await getSolarReturnChart({
natal: {
date: { year: 1990, month: 6, day: 15, hour: 14, minute: 30 },
latitude: 48.856,
longitude: 2.352,
},
year: 2026,
solarReturnLatitude: 40.7128, // optional relocated SR
solarReturnLongitude: -74.006,
solarReturnHouseSystem: HouseSystem.WHOLE_SIGN, // optional
});
sr.natalChart // BirthChart
sr.solarReturnChart // BirthChart — cast at exactReturnDate, SR location
sr.exactReturnDate // Date (UTC)
sr.natalSunLongitude // number — natal Sun longitude used for search
sr.year // number

SolarReturnOptions

FieldTypeDefaultDescription
natalBirthChartOptionsrequiredNatal chart options.
yearnumberrequiredTarget year for the return.
solarReturnLatitudenumbernatal latitudeRelocated SR location.
solarReturnLongitudenumbernatal longitudeRelocated SR location.
solarReturnHouseSystemHouseSystemnatal house systemSR chart house system.

6. Profections

Pure math — requires a whole-sign BirthChart, but no additional WASM calls.

import { getAnnualProfection, getMonthlyProfections } from 'kaabalah/astrology';

Profections are a Hellenistic time-lord technique that advances the Ascendant one house per year. Each house corresponds to a sign, and that sign’s domicile ruler becomes the time lord for the year.

getAnnualProfection(natalChart, birthDate, targetYear?): AnnualProfection

// natalChart must use HouseSystem.WHOLE_SIGN
const chart = await getBirthChart({
date: new Date('1990-06-15'),
latitude: 48.856,
longitude: 2.352,
houseSystem: HouseSystem.WHOLE_SIGN,
});
const profection = getAnnualProfection(chart, new Date('1990-06-15'), 2026);
// { age: 36, house: 1, sign: "Virgo", ruler: "Mercury", targetYear: 2026 }
Return fieldTypeDescription
agenumberAge at start of the profection year.
housenumberActivated house (1–12).
signstringSign on the activated house cusp.
rulerTraditionalPlanetDomicile ruler = time lord for the year.
targetYearnumberThe year queried.

getMonthlyProfections(natalChart, birthDate, targetYear?): MonthlyProfectionsResult

Returns the annual profection plus 12 monthly sub-profections, each advancing one sign from the annual sign, starting on the birthday each month.

const monthly = getMonthlyProfections(chart, new Date('1990-06-15'), 2026);
monthly.annualProfection // AnnualProfection
monthly.months // MonthlyProfection[]
// monthly.months[0] = { month: 1, startDate: Date, sign: "Virgo", ruler: "Mercury" }

7. Firdaria

Pure math — no WASM dependency.

import { getFirdaria } from 'kaabalah/astrology';

getFirdaria(birthDate, isDiurnal, targetDate?, options?): FirdariaResult

Computes the 75-year planetary period cycle. Sect determines the sequence order: diurnal charts begin with the Sun; nocturnal charts begin with the Moon. Sub-periods follow Chaldean descent from the major period ruler.

const firdaria = getFirdaria(
new Date('1990-06-15'),
true, // isDiurnal — use chart.sect === 'diurnal'
new Date('2026-04-22'),
{ nodeSubPeriodStart: 'jupiter-saturn' } // optional
);
firdaria.sect // "diurnal"
firdaria.currentMajor // FirdariaMajorPeriod
firdaria.currentSub // FirdariaSubPeriod
firdaria.allPeriods // FirdariaMajorPeriod[]

Diurnal sequence (75 years total): Sun 10y → Venus 8y → Mercury 13y → Moon 9y → Saturn 11y → Jupiter 12y → Mars 7y → North Node 3y → South Node 2y

Nocturnal sequence: Moon 9y → Saturn 11y → Jupiter 12y → Mars 7y → North Node 3y → South Node 2y → Sun 10y → Venus 8y → Mercury 13y

FirdariaMajorPeriod:

FieldTypeDescription
planetFirdariaPlanetMajor period ruler.
yearsnumberDuration of the major period.
startDateDatePeriod start.
endDateDatePeriod end.
subPeriodsFirdariaSubPeriod[]7 equal sub-periods in Chaldean descent.

FirdariaOptions:

FieldTypeDefaultDescription
nodeSubPeriodStart"jupiter-saturn" | "sun-mars""jupiter-saturn"Controls which Chaldean position the North/South Node sub-periods start from.

8. Aspects

Pure math — no WASM dependency.

import {
computeAspects,
computeSynastryAspects,
computeMidpoints,
getAspectMatch,
DEFAULT_ASPECT_SPECS,
} from 'kaabalah/astrology';

getAspectMatch(lonA, lonB, specs?)

Check whether two ecliptic longitudes form any aspect. Returns the matching spec and orb, or null.

const match = getAspectMatch(15, 105);
// { spec: { name: "square", angle: 90, orb: 6 }, orb: 0, delta: 90 }

computeAspects(planets, specs?): AspectEdge[]

All unique intra-chart aspects among a set of points.

const aspects = computeAspects({
sun: { longitude: 84.5 },
moon: { longitude: 210.3 },
ascendant: { longitude: 165.0 },
});

computeSynastryAspects(planetsA, planetsB, specs?): AspectEdge[]

All cross-chart aspects — every point in A vs every point in B.

const crossAspects = computeSynastryAspects(
{ sun: { longitude: 84.5 }, moon: { longitude: 210.3 } },
{ sun: { longitude: 120.1 }, moon: { longitude: 300.0 } }
);

computeMidpoints(planetsA, planetsB): Record<string, number>

Shorter-arc midpoint longitude for each planet that exists in both maps. Used internally by getCompositeChart.

const midpoints = computeMidpoints(
{ sun: { longitude: 84.5 }, moon: { longitude: 210.3 } },
{ sun: { longitude: 120.1 }, moon: { longitude: 300.0 } }
);
// { sun: 102.3, moon: 255.15 }

DEFAULT_ASPECT_SPECS

AspectAngleDefault orb
conjunction
duodecile30°
octile45°
sextile60°
square90°
trine120°
trioctile135°
quincunx150°
opposition180°

AspectEdge:

FieldTypeDescription
planetAstringFirst point name.
planetBstringSecond point name.
longitudeAnumberLongitude of point A.
longitudeBnumberLongitude of point B.
aspectAspectNameAspect name.
aspectAnglenumberExact aspect angle.
deltanumberShorter arc between the two points.
orbnumberDeviation from exact (degrees).

9. Astrocartography

Pure math — no WASM dependency (uses pre-computed equatorial positions synchronously).

import {
queryAstrocartographyLocation,
computeAstrocartographyMap,
computeGMST,
computeMCLongitude,
computeICLongitude,
computeHorizonLongitude,
findParansAtLatitude,
ASTROCARTOGRAPHY_DEFAULT_PLANETS,
} from 'kaabalah/astrology';

queryAstrocartographyLocation(date, options): AstrocartographyQueryResult

Primary API. For a natal UTC date and a query location, returns how close each planet/angle line is to that location, which lines are active (within orb), and any paran crossings at the query latitude.

const result = queryAstrocartographyLocation(chart.dateUtc, {
latitude: 51.5,
longitude: -0.12,
orb: 3, // default 2
paranOrb: 1, // default 1
planets: ASTROCARTOGRAPHY_DEFAULT_PLANETS, // optional subset
});
result.lines // AstrocartographyLineProximity[] — sorted by distance
result.activeLines // AstrocartographyLineProximity[] — within orb
result.parans // AstrocartographyParan[]

AstrocartographyLineProximity:

FieldTypeDescription
planetstringPlanet name.
angle"MC" | "IC" | "AC" | "DC"Angle line type.
distancenumberDegrees of longitude separation (0–180).
activebooleanTrue when distance ≤ orb.
longitudenumberGeographic longitude of the line (−180 to 180).

AstrocartographyParan:

FieldTypeDescription
latitudenumberQuery latitude.
planetA / planetBstringTwo planets sharing this latitude.
angleA / angleBAngleTypeTheir respective angle types.
longitudeA / longitudeBnumberTheir geographic longitudes.

computeAstrocartographyMap(date, options?): AstrocartographyMap

Generates the complete ACG map: MC/IC lines as constant longitudes, AC/DC lines as arrays of latitude/longitude points from a latitude sweep.

const map = computeAstrocartographyMap(chart.dateUtc, {
latitudeStep: 1, // default 1 degree
latitudeRange: 66.5, // default 66.5 (polar circle)
});
map.meridianLines // AstrocartographyMeridianLine[]
map.horizonLines // AstrocartographyHorizonLine[]

Lower-level helpers

FunctionSignatureDescription
computeGMST(julianDay) → numberGreenwich Mean Sidereal Time in degrees.
computeMCLongitude(gmst, ra) → numberGeographic longitude of a planet’s MC line (−180..180).
computeICLongitude(gmst, ra) → numberGeographic longitude of a planet’s IC line.
computeHorizonLongitude(gmst, ra, dec, latitude, "AC"|"DC") → number | nullGeographic longitude of AC or DC line at a latitude. Returns null if circumpolar.
findParansAtLatitude(positions, gmst, latitude, paranOrb?) → AstrocartographyParan[]Paran crossings at a latitude from pre-computed equatorial positions.

ASTROCARTOGRAPHY_DEFAULT_PLANETS: Sun, Moon, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, Chiron, True Node.


10. Essential Dignity

Pure math — no WASM dependency.

import {
getEssentialDignity,
getDomicileRuler,
getExaltation,
getDetriment,
getFall,
getOppositeSign,
DOMICILE_RULERS,
EXALTATIONS,
} from 'kaabalah/astrology';

Traditional Hellenistic rulership data for the seven classical planets.

getEssentialDignity(planet, sign): EssentialDignityResult

Comprehensive dignity assessment for a planet in a sign.

const dignity = getEssentialDignity('Saturn', 'Libra');
// { domicile: false, exaltation: true, detriment: false, fall: false,
// domicileRuler: "Venus", peregrine: false }

EssentialDignityResult:

FieldTypeDescription
domicilebooleanPlanet rules this sign.
exaltationbooleanPlanet is exalted here.
detrimentbooleanPlanet is in detriment here.
fallbooleanPlanet is in fall here.
domicileRulerTraditionalPlanetThe sign’s domicile ruler (may differ from the queried planet).
peregrinebooleanNone of domicile, exaltation, detriment, or fall.

Individual lookup functions

getDomicileRuler('Scorpio') // "Mars"
getExaltation('Saturn') // { sign: "Libra", degree: 21 }
getDetriment('Mars') // ["Libra", "Taurus"]
getFall('Jupiter') // "Capricorn"
getOppositeSign('Aries') // "Libra"

TraditionalPlanet values: "Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn".


11. Decans

Pure math — no WASM dependency.

import { getDecan } from 'kaabalah/astrology';

getDecan(longitude): DecanResult

Returns the decan (face) for an ecliptic longitude using Chaldean rulers and the Golden Dawn tarot correspondence.

const decan = getDecan(84.5); // 24°30' Gemini
// {
// sign: "Gemini",
// decanNumber: 3,
// ruler: "Saturn",
// tarotCard: "Ten of Swords",
// startDegree: 80,
// endDegree: 90,
// degreeWithinSign: 24.5,
// }

DecanResult:

FieldTypeDescription
signstringZodiac sign.
decanNumber1 | 2 | 3Which decan within the sign.
rulerTraditionalPlanetChaldean ruler of this decan.
tarotCardstringGolden Dawn minor arcana card (e.g. "Five of Wands").
startDegreenumberAbsolute ecliptic longitude start (0–360).
endDegreenumberAbsolute ecliptic longitude end (0–360).
degreeWithinSignnumberPosition within the sign (0–30).

12. Dodecatemoria

Pure math — no WASM dependency.

import { getDodecatemoria } from 'kaabalah/astrology';

getDodecatemoria(longitude): DodecatemoriaResult

Computes the 12th-part (dodecatemoria) for an ecliptic longitude. Each 2.5° segment of a sign maps to one of the 12 signs starting from the sign itself.

const result = getDodecatemoria(5.0); // 5° Aries
// {
// originalSign: "Aries",
// originalDegree: 5,
// dodecatemoriaSign: "Taurus",
// dodecatemoriaIndex: 1,
// }

DodecatemoriaResult:

FieldTypeDescription
originalSignstringSign of the input longitude.
originalDegreenumberDegree within the original sign (0–30).
dodecatemoriaSignstringThe 12th-part sign.
dodecatemoriaIndexnumber0–11 offset from the original sign.

13. Utility functions

Pure math — no WASM dependency.

import {
formatDegreeMinutes,
getZodiacPosition,
findHouseOf,
normalizeAngle,
SIGNS,
} from 'kaabalah/astrology';
FunctionSignatureDescription
formatDegreeMinutes(decimalDegrees) → stringFormats a decimal degree as "9°48'".
getZodiacPosition(longitude, houseCusps) → ZodiacPositionConverts a 0–360 longitude to a full ZodiacPosition including house.
findHouseOf(longitude, housePositions) → numberReturns the house number (1–12) for a longitude given cusp array.
normalizeAngle(angle) → numberWraps any angle to 0–360.
SIGNSreadonly string[]["Aries", ..., "Pisces"] — 12 sign names in order.