Skip to main content

lxephemeris

The modern astronomical & astrological computation engine for Python, Node.js, and Rust.
100% memory-safe Rust core (#![forbid(unsafe_code)]). Lock-free multi-threading. Zero external files required to start — with native NASA JPL DE440s support for < 0.003" precision.

CI PyPI npm Crates.io License

import lxephemeris

# Works out of the box with zero external files (or loads NASA JPL DE440s if present)
engine = lxephemeris.Engine()

jd_utc = lxephemeris.utc_from_local(2026, 10, 27, 14, 30, 0.0, tz_name="America/New_York")
obs = lxephemeris.Observer(latitude_deg=40.7128, longitude_deg=-74.0060, altitude_m=10.0)

# Full natal snapshot: planets, 23 house systems, aspects, Hermetic lots, lunar phase & sect in ~150 µs
chart = engine.chart_snapshot(jd_utc, obs)

Why lxephemeris?

Legacy backends stitch together 30-year-old C bindings (pyswisseph), PyEphem, and Kerykeion — inheriting process-global mutable C state, thread race conditions, silent polar house errors, and slow FFI loops. lxephemeris replaces the entire stack with a single clean-room Rust engine:

  • One Engine Replaces 6+ Libraries: Ships 10 planets, 68 JPL minor bodies (Chiron, Ceres, Eris, Sedna, Lilith (1181)...), 7 Lunar nodes/apogees, 9 Uranians, 23 house systems (with explicit polar policies), 43+1 sidereal ayanamsas, 52 Hipparcos-2/XHIP fixed stars, solar/lunar eclipses & occultations, Vedic Panchanga / 16 Vargas / Vimshottari Dasha, Traditional Sect / Planetary Hours / 7 Hermetic Lots, Human Design 64 Gates & -88° arc, 24 Chinese Solar Terms (Jieqi), and native Transit / Return / Station / VoC Moon solvers.
  • Lock-Free Thread Safety & Memory Safety: #![forbid(unsafe_code)], Send + Sync, zero global C state, zero locks required across concurrent Tropical, Sidereal, and Topocentric requests.
  • 5–15× Faster: Single-pass analytical velocity Jacobians (12.8 µs/body with speed; ~150 µs/full natal chart) + GIL-free Rayon multi-core batching.
  • 22 Upstream Bugs Eliminated: Fixes global C races, ±66° latitude clamps (7.85° Svalbard ASC error), Mira/Mirach star collisions, star-anchor aberration wobble, and Sun().hlong $180^\circ$ inversions.
  • Drop-In SweAdapter: Migrate existing pyswisseph codebases in minutes without rewriting call sites.

👉 Read the full architectural deep-dive & 22 eliminated legacy bugs →

☁️ Want a Turnkey Cloud API Instead of Self-Hosting?

lxephemeris is the low-level astronomical & astrological math engine that powers AstroAPI (astrology-api.io) and Astrolium (astrolium.com).

If you are building a commercial astrology app, SaaS, or mobile product and don't want to maintain your own ephemeris infrastructure — or purchase a self-hosted commercial engine license — use AstroAPI directly:

  • Turnkey REST API powered by lxephemeris in production
  • Built-in City Geocoding & Historical Timezone / DST Resolution (birth city + date/time → full chart)
  • SVG Chart Wheel Rendering, Synastry Compatibility Scoring, and Structured Interpretations
  • Commercial Rights Included: Your AstroAPI subscription includes commercial production usage — no separate lxephemeris commercial license required.

How lxephemeris Compares

Feature lxephemeris Swiss Ephemeris (pyswisseph) Kerykeion PyEphem (ephem) Skyfield
Core Architecture 100% Safe Rust (#![forbid(unsafe_code)]) Legacy C (libswe, 1990s) Python wrapper over pyswisseph Legacy C (libastro) Pure Python / NumPy
Thread Safety Lock-free Send + Sync (0 state bleed) ❌ Global mutable C static state ❌ Inherits pyswisseph globals ⚠️ Mutable Body objects ✅ Thread-safe
Works with 0 External Files ✅ Built-in analytical engine (-3000..+3000) ⚠️ Silent fallback if .se1 missing ✅ Bundles .se1 files ✅ Analytical only ❌ Requires downloading .bsp
JPL DE440s / DE441 Precision ✅ Native DAF/SPK (< 0.003") Compressed .se1 re-fits Via pyswisseph ❌ Truncated VSOP87 (multi-arcsec drift) ✅ Native SPK
Single Body + Speed Latency 12.8 µs (analytical Jacobian) ~45–90 µs (3-pt finite diff) ~25–80 ms per subject ~80–150 µs ~600–2,000 µs
23 Houses & Arctic/Polar Safety ✅ All 23 + explicit PolarPolicy ⚠️ Silent polar fallback & house_pos=0.0 bug ❌ Clamps |lat| > 66° (7.85° ASC error) ❌ No astrological houses ❌ No astrological houses
68 Astrological Minor Bodies ✅ Single verified .bsp + Keplerian fallback Manage 68 separate .se1 files Partial ❌ Manual orbital elements Manual SPK segments
43+1 Sidereal Ayanamsas ✅ Aberration-free star anchors ⚠️ ±20.5" annual aberration wobble on star anchors ⚠️ Leaves secondary points tropical ❌ None ❌ None
Transit, Return & VoC Moon Solvers ✅ Native Rust Newton-Illinois solvers ❌ Write your own FFI loops ❌ Static charts only ❌ Basic rising/phase only Discrete almanac only
Vedic (Panchanga, Dasha, D1–D60) ✅ Built-in ❌ None ❌ None ❌ None ❌ None
Traditional (Sect, Hours, 7 Lots) ✅ Built-in ❌ None ❌ None ❌ None ❌ None
Human Design (64 Gates & -88° Arc) ✅ Built-in ❌ None ❌ None ❌ None ❌ None
SDKs with Identical Math Python, Node.js/TS, Rust, CLI C + separate 3rd-party bindings Python only Python only Python only

Quickstart

Installation

# Python (PyPI)
pip install lxephemeris

# Node.js / TypeScript (npm)
npm install lxephemeris

# Rust Library & CLI (crates.io)
cargo add lxephemeris-core
cargo install lxephemeris-cli

Python (lxephemeris)

import lxephemeris

# 1. Start immediately (zero external files needed) or load NASA JPL DE440s from ./data
engine = lxephemeris.Engine()
# engine = lxephemeris.Engine.from_data_dir("./data", verify_manifest_sha256=True)

# 2. Local wall-clock time -> UTC Julian Date (preserves fractional seconds & PEP 495 DST fold)
jd_utc = lxephemeris.utc_from_local(2026, 10, 24, 14, 0, 32.5, tz_name="Europe/Berlin", fold=0)
obs = lxephemeris.Observer(51.5074, -0.1278, 35.0)

# 3. Single body position + analytical speed + visual magnitude
sun = engine.calc("Sun", jd_utc, scale="UTC")
chiron = engine.calc("Chiron", jd_utc, scale="UTC")
print(f"Sun: {sun.lon_deg:.6f}° (speed={sun.lon_speed_deg_day:.6f}°/d, Vmag={sun.magnitude_v:.2f})")

# 4. Polar-safe houses & cusp boundary guard (eps = 1e-9°)
houses = engine.houses(
    jd_utc,
    latitude_deg=51.5074,
    longitude_deg=-0.1278,
    system="P",
    scale="UTC",
    polar_policy="fallback_to_whole_sign",
)
sun_house = lxephemeris.house_of_lon(sun.lon_deg, houses.cusps_deg, eps_deg=1e-9)

# 5. All-in-one Natal Snapshot, Solar Return, Vedic Panchanga, & Human Design Gate
snapshot = engine.chart_snapshot(jd_utc, obs)
solar_return = engine.planetary_return("Sun", jd_utc, jd_utc + 350.0)
panchanga = engine.panchanga(jd_utc, obs, ayanamsa="lahiri")
hd = lxephemeris.map_zodiac_placement(sun.lon_deg)
print(f"ASC: {houses.asc_deg:.4f}° | Sun in House {sun_house} | HD Gate {hd.hd_gate}.{hd.hd_line}")

Node.js / TypeScript (lxephemeris)

import { Engine, utcFromLocal, houseOfLon, mapZodiacPlacement } from "lxephemeris";

const engine = new Engine();
// const engine = Engine.fromDataDir("./data", 4, null, true);

const jdUtc = utcFromLocal(2026, 10, 24, 14, 0, 32.5, "Europe/Berlin");
const jdSplit = { jd1: jdUtc, jd2: 0.0 };
const obs = { latitudeDeg: 51.5074, longitudeDeg: -0.1278, altitudeM: 35 };

const sun = engine.calc("Sun", jdSplit, "UTC");
const houses = engine.houses(jdSplit, obs, "P", "UTC", "fallback_to_whole_sign");
const sunHouse = houseOfLon(sun.lonDeg, houses.cuspsDeg, 1e-9);
const snapshot = engine.chartSnapshot(jdUtc, obs);
const hd = mapZodiacPlacement(sun.lonDeg);

console.log(
  `Sun: ${sun.lonDeg.toFixed(6)}° in House ${sunHouse} | HD Gate ${hd.hdGate}.${hd.hdLine} | Lots: ${snapshot.lots.length}`
);

Rust (lxephemeris-core)

use lxephemeris_core::{
    AspectPreset, BodyId, CalcOptions, Engine, HouseOptions, HouseSystem, Observer,
    PlanetId, PolarPolicy, TimeInput, JD_J2000,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let engine = Engine::default();
    let t = TimeInput::from_tt_jd(JD_J2000);
    let sun = engine.calc(BodyId::Planet(PlanetId::Sun), t, CalcOptions::default())?;

    let obs = Observer::new(51.5074, -0.1278, 35.0)?;
    let houses = engine.houses(
        t,
        obs,
        HouseOptions {
            system: HouseSystem::Placidus,
            polar_policy: PolarPolicy::FallbackToWholeSign,
            ..Default::default()
        },
    )?;
    let snapshot = engine.chart_snapshot(
        t,
        obs,
        &[BodyId::Planet(PlanetId::Sun), BodyId::Planet(PlanetId::Moon)],
        HouseOptions::default(),
        CalcOptions::default(),
        AspectPreset::Major,
        1.0,
    )?;
    println!("Sun={:.6}°, ASC={:.4}°, Lots={}", sun.lon_deg, houses.angles.asc_deg, snapshot.lots.len());
    Ok(())
}

CLI (lxephemeris-cli)

lxephemeris-cli calc --jd 2460676.5 --bodies Sun,Moon,Chiron
lxephemeris-cli houses --jd 2460676.5 --lat 51.5074 --lon -0.1278 --system P
lxephemeris-cli panchanga --jd 2460676.5 --lat 28.6139 --lon 77.2090 --ayanamsa lahiri
lxephemeris-cli fetch-kernel --kernel de440s --data-dir ./data

Verification & Benchmarks

Verified against 37,416 golden reference vectors from NASA JPL Horizons (DE440 / SB441-N16), IAU SOFA, and USNO across 145+ Rust tests, 18 Python test suites, and 12 Node.js test suites (100% PASS). Single-body position + analytical velocity runs in 12.8 µs; a full natal chart runs in ~150–240 µs.

👉 Full Verification & Benchmark Report (ACCEPTANCE_REPORT.md) →


Documentation


Licensing & Commercial Use

lxephemeris is dual-licensed (LICENSE.md). Choose the option that fits your deployment:

Option Best For Commercial Rights How to Start
☁️ AstroAPI (Managed Cloud API) Web/mobile apps, SaaS startups & teams wanting turnkey REST endpoints, city geocoding, SVG chart wheels & interpretations ✅ Included in API subscription Start at astrology-api.io →
🏢 lxephemeris Commercial License (LicenseRef-Commercial) Self-hosted backends, high-throughput batch pipelines & on-premise services running lxephemeris on your own servers ✅ Included via offline Ed25519 key (LXEPHEMERIS_LICENSE_KEY) Request License (procoders.tech/contacts) → or lxephemeris@procoders.tech
🎓 lxephemeris Non-Commercial (PolyForm-Noncommercial-1.0.0) Personal projects, academic research, education, non-profits & 30-day pre-purchase commercial evaluation ❌ Non-commercial & 30-day staging eval only pip install lxephemeris / npm i lxephemeris

👉 Full Dual-Licensing Policy & Offline Key Activation (LICENSE.md) →

Metadata

Release files for lxephemeris 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lxephemeris 1.0.1
File Size Uploaded Provenance Actions
lxephemeris-1.0.1.tar.gz 371.0 kB Without provenance Details for lxephemeris-1.0.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for lxephemeris 1.0.1
File Actions
lxephemeris-1.0.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details for lxephemeris-1.0.1-cp39-abi3-win_amd64.whl
lxephemeris-1.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details for lxephemeris-1.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
lxephemeris-1.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details for lxephemeris-1.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
lxephemeris-1.0.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details for lxephemeris-1.0.1-cp39-abi3-macosx_11_0_arm64.whl
lxephemeris-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details for lxephemeris-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl

Total release size: 8.3 MB

Release files / lxephemeris-1.0.1.tar.gz

Download URL lxephemeris-1.0.1.tar.gz
Size 371.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6db92819811cee83b0b06a14fdbdd5e6b0c2cc722d0dfe5ef9675169cf4e4553
BLAKE2b-256 checksum
How to use checksums
0a5f902fb3c54787fa3e1e8702a4cc17967cd1a469808e8e920d76a3f6c75ec0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.16.0

Release files / lxephemeris-1.0.1-cp39-abi3-win_amd64.whl

Download URL lxephemeris-1.0.1-cp39-abi3-win_amd64.whl
Size 1.5 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
8c02edf50552309965474c4a0903db07927eeb00cbe4fbe3b23e2f600d75e12d
BLAKE2b-256 checksum
How to use checksums
3c8c343bceac02453c03a994c8d81f0eec14a448b077f51f98dc233b13e17935
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.16.0

Release files / lxephemeris-1.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL lxephemeris-1.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.7 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
6d38542c01b609c6db7fb4bd00e96d49fc463ee9ba55bc15e727297b07b4b87f
BLAKE2b-256 checksum
How to use checksums
c8d8f2193436d03a3a86f377fb89cb63dbccedc95d7d687a49ecc3a7cd1b1c12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.16.0

Release files / lxephemeris-1.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL lxephemeris-1.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 1.7 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
a337d77efd0011e443b6c4c360d9580d2dd5f504b071486fc6182e2efca968f8
BLAKE2b-256 checksum
How to use checksums
3f255c28b5f6816c6cdf35cfee07266bc1b9570079b93d91f9e16749cc6f6817
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.16.0

Release files / lxephemeris-1.0.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL lxephemeris-1.0.1-cp39-abi3-macosx_11_0_arm64.whl
Size 1.5 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4b5057f8d0bd6259fd0fcbba55bd20cbb67cbb1089b0129d611c18461cfe2d7b
BLAKE2b-256 checksum
How to use checksums
58e6cdf1d17646d640f596203c55d94cf005c1c1c651560e03e2d2a10c9006aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.16.0

Release files / lxephemeris-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl

Download URL lxephemeris-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl
Size 1.6 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
598bb6bd6425f35bba98577f690794dde1bda1825868470cde63eaaa03c49e28
BLAKE2b-256 checksum
How to use checksums
43ad160abafa1dc2d361010c515ce5a373f9c4c9f512578336e1195f76a1b7dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.16.0

Security for lxephemeris 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.1 This release

6 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page