Every astrology library can tell you the Sun is in Scorpio. As of 0.1.1, OxiEphemeris can also tell a SPARQL query that Scorpio is a skos:Concept with a Wikidata QID — and hand that same chart to Python or a browser tab without recomputing a single degree.
Today we released OxiEphemeris 0.1.1 — a Linked Open Data release: a full RDF/SKOS/PROV-O astrology vocabulary with a SPARQL store and HTTP endpoint, a UI-free chart-computation facade shared bit-for-bit by the CLI and new Python and WebAssembly bindings, and a substantially deeper astrology layer — sidereal ayanamshas, essential dignities, declinations, Arabic Parts, midpoints, and synastry cross-aspects.
No C. No Fortran. No libswe, no pyswisseph FFI at runtime — the README’s 960-case Swiss Ephemeris comparison was run once, offline, against a binary wheel, with its results checked into committed fixture files; pyswisseph itself is never linked into the build. No RocksDB either: the new SPARQL store builds its oxigraph dependency with default-features = false, which drops the C++ storage engine entirely and leaves a pure-Rust in-memory store. The whole workspace runs unsafe_code = "forbid" at the lint level, with zero .unwrap()/.expect() in library code (clippy::unwrap_used/expect_used denied workspace-wide). It compiles to a single static binary — or to WebAssembly, running a full chart computation entirely offline in a browser tab — and runs everywhere Rust runs.
Why OxiEphemeris 0.1.1 is a game changer
The incumbents in this space all share the same shape of compromise:
- Swiss Ephemeris — the de facto standard, wrapped by
pyswisseph— is a C library behind an FFI boundary, dual-licensed AGPL/commercial, so every binding pays a C-toolchain tax at build time and a licensing conversation before you ship. - PyEphem is Python-only: no shared compute core for a browser or a CLI, and no Linked Open Data output of any kind.
- JavaScript astrology libraries are typically a separate reimplementation of the same math, not a shared core — a chart computed in the browser and a chart computed on a server can quietly disagree.
- None of them expose a chart as queryable Linked Open Data: no
skos:Conceptfor a sign, no dereferenceable IRI for a Sun placement, no way toSPARQLacross a chart the way you’d query any other structured dataset.
OxiEphemeris 0.1.1 ends all of that:
- A real RDF vocabulary, generated from the engine’s own code. The new
oxiephemeris-rdfcrate’soxa:/oxc:/oxs:classes and SKOS concept schemes are generated from the same enums and dignity tables that compute charts, with bilingual English/Japanese labels and Wikidata QID cross-references for every planet and sign — the vocabulary cannot silently drift out of sync with the engine. - A live public SPARQL endpoint today, not a roadmap item.
https://sparql.cooljapan.tech/already serves theoxa:/oxc:/oxs:IRIs as dereferenceable Turtle, N-Triples, and HTML, and answers SPARQL 1.1 Protocol queries — verifiable with a singlecurl(see Tips below). - One compute path, three front ends. The new
oxiephemeris-chartfacade is now the single source of truth fornatal_chart/synastry/transit/progression/composite, shared bit-identically by the CLI, the new PyO3 Python bindings, and the new WebAssembly bindings — the same numbers, no matter which one computed them. - A genuinely deeper astrology layer, not just new bindings. Sidereal ayanamshas (5 systems), essential dignities, declinations with antiscia, Arabic Parts, midpoints, and full synastry cross-aspects all landed in the same release — the README’s own cross-checks put the Lahiri ayanamsha at epoch 1999 at 23.851°, matching the published 23°51′, and the sidereal longitude convention agrees with the independent
oxiephemeris-compatimplementation to under 1e-6°. - 490 tests green across the workspace,
--all-features, including new graph-closure tests that assert every RDF predicate this release can emit was actually declared in the vocabulary.
Technical Deep Dive: from a DE kernel to a dereferenceable IRI
- Time and ephemeris (
oxiephemeris-core,oxiephemeris-de) — the unchanged foundation, plus one new hook. Two-partJulianDate(hi/lo) arithmetic, proleptic Gregorian/Julian calendar conversions, an embedded UTC leap-second table, the Fairhead–Bretagnon TT↔TDB series, and the 15-piece Espenak–Meeus ΔT polynomial have shipped since 0.1.0.oxiephemeris-dereads JPL’s classic DE440/DE441 binary format and the SPK/DAF.bspcontainer (segment types 2, 3, and 13) via Chebyshev interpolation over Clenshaw recurrence. 0.1.1 adds exactly one new primitive here:DeFile::de_number(), exposing the DE header’sNUMDEfield — added purely so the RDF layer three levels up can record which ephemeris a chart’s provenance graph actually came from. - Frames and astrology (
oxiephemeris-bodies,oxiephemeris-astro) — where 0.1.1’s real depth lands.oxiephemeris-bodiessupplies IAU 2006 frame bias/precession (Fukushima–Williams angles), the full IAU 2000A_R06 nutation series with a 2000B-class fast path, and the apparent-place pipeline (light-time iteration, aberration, optional light deflection) — also since 0.1.0.oxiephemeris-astrois where 0.1.1’s new modules live:ayanamsha(five sidereal systems — Fagan/Bradley, Lahiri, Krishnamurti, Raman, J2000-zero, plus a custom-anchor mode — propagated from cited epochs via the IAU 2006 P03 general-precession polynomial),dignities(domicile/exaltation/triplicity/term/face rulers, detriment/fall/peregrine, a configurableRulershipScheme),declination(ecliptic→equatorial conversion, antiscia, and parallel/contraparallel/out-of-bounds classification, cross-checked against an independent rotation-based oracle),parts(Sect-aware Arabic Parts),midpoints, andsynastry(CrossHit,for_each_cross_aspect— the engine behind the CLI’s newsynastry/transit/progress/compositecommands). - The chart facade and its three front ends (
oxiephemeris-chart,oxiephemeris-cli,oxiephemeris-py,oxiephemeris-wasm) — entirely new in 0.1.1.oxiephemeris-chartis the UI-free compute layer:natal_chart,synastry,transit,progression, andcomposite, each returning aChartResource/ChartComparison/CompositeChartResourcethat renders to JSON or RDF throughchart_to_json/chart_to_rdfand friends, with its own dependency-free ISO 8601 parser instead of pulling inchrono.oxiephemeris-cli’schart/houses/synastry/transit/progress/compositecommands are now thin renderers over this facade — epoch resolution moved out of the CLI’s own code and intooxiephemeris_chart::epoch— and the newoxiephemeris-py(PyO3,abi3-py38) andoxiephemeris-wasm(wasm-bindgen) crates call the exact same functions underneath. - Linked Open Data (
oxiephemeris-rdf,oxiephemeris-lod) — the release’s headline layer.oxiephemeris-rdfdefines theoxa:/oxc:/oxs:vocabulary plus PROV-O provenance and canonical, byte-stable Turtle/N-Triples serialization — triples are sorted before every write, so re-emitting the same chart never produces a spurious diff.oxiephemeris-lodsits above it:FileBackedStoreis an in-memoryoxigraphStorebuilt withdefault-features = false(no RocksDB) plus whole-file N-Quads persistence via atomic rename;endpoint::handleimplements the SPARQL 1.1 Protocol as a pure function, testable without ever binding a socket; andoxieph-sparqldis the thin binary wiring both tooxhttp.
Getting Started
cargo install oxiephemeris-cli
Two commands, zero and one file dependency respectively:
# The oxa:/oxc:/oxs: RDF vocabulary itself — no DE kernel needed.
oxieph vocab --part ontology --format turtle
# Synastry: cross-aspects between two natal charts (new in 0.1.1).
oxieph synastry --date-a 1970-01-01T00:00:00 --lat-a 51.4779 --lon-a 0.0 \
--date-b 2000-01-01T12:00:00 --lat-b 48.8566 --lon-b 2.3522 \
--de data/de440/linux_p1550p2650.440
From Rust, the same compute path via oxiephemeris-chart:
cargo add oxiephemeris-chart oxiephemeris-de
use oxiephemeris_chart::{chart_to_json, chart_to_rdf, natal_chart, NatalSpec, RdfFormat};
use oxiephemeris_de::DeFile;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bytes = std::fs::read("data/de440/linux_p1550p2650.440")?;
let de = DeFile::parse(&bytes)?;
// The Unix epoch at the Royal Observatory, Greenwich — 0.1.1's
// canonical reference chart, used throughout the tests and docs.
let spec = NatalSpec {
date: "1970-01-01T00:00:00Z".to_owned(),
lat: 51.4779,
lon: 0.0,
alt: 0.0,
dut1: 0.0,
cal: "gregorian".to_owned(),
system: "placidus".to_owned(),
sidereal: None,
rulership: "traditional".to_owned(),
};
let chart = natal_chart(&de, &spec.into_request()?)?;
let json = chart_to_json(&chart)?; // stable JSON schema
let turtle = chart_to_rdf(&chart, None, None, RdfFormat::Turtle)?; // RDF, default base IRI
println!("{json}\n{turtle}");
Ok(())
}
The Python and WebAssembly bindings are new source in this release but aren’t packaged for PyPI/npm yet — build them from source. Python, via maturin:
cd crates/oxiephemeris-py && maturin develop
import oxiephemeris as oxi
with open("de440/linux_p1550p2650.440", "rb") as f:
de = f.read()
chart = oxi.natal(de, "1970-01-01T00:00:00Z", lat=51.4779, lon=0.0)
sun = next(b for b in chart["bodies"] if b["body"] == "Sun")
print(sun["sign"], round(sun["sign_degrees"], 2), "house", sun["house"])
# -> Capricorn 10.16 house 4
WebAssembly, via wasm-pack (the www/index.html demo page in the crate is a self-contained example):
wasm-pack build crates/oxiephemeris-wasm --target web --out-dir pkg
What’s New in 0.1.1
- Linked Open Data layer (
oxiephemeris-rdf): theoxa:/oxc:/oxs:vocabulary generated from the engine’s own enums and dignity tables, PROV-O provenance, canonical byte-stable Turtle/N-Triples output, bilingual English/Japanese labels, Wikidata QID cross-references, and graph-closure tests. - SPARQL store and HTTP endpoint (
oxiephemeris-lod): a pure-RustFileBackedStore(no RocksDB), a pure-function SPARQL 1.1 Protocol handler, and theoxieph-sparqldbinary (--bind,--store,--read-only,--load,--vocab). - Chart-computation facade (
oxiephemeris-chart):natal_chart,synastry/transit/progression/composite, and their JSON/RDF serializers — the single compute path now shared by the CLI, Python, and WASM. - Python bindings (
oxiephemeris-py, PyO3,abi3-py38):julday,revjul,natal,natal_rdf,synastry,synastry_rdf,transit,progress,composite,composite_rdf. - WebAssembly bindings (
oxiephemeris-wasm): natal, synastry, transit, progression, and composite charts, including RDF Turtle output, computed entirely offline in the browser. - Astrology layer additions (
oxiephemeris-astro): sidereal ayanamshas (5 systems), essential dignities, declinations + antiscia, Arabic Parts, midpoints, motion classification, and synastry cross-aspects. - CLI: five new subcommands (
synastry,transit,progress,composite,vocab) and a unified--format text|json|turtle|ntriplesflag across every chart-family command (the legacy--jsonflag still works). - Changed: the CLI’s
chart/housescommands became thin renderers over the new facade; RDF output plumbing consolidated into an internalRdfOutputstruct; MSRV raised from 1.81 to 1.89 for the new RDF/SPARQL dependency stack; the reference chart across tests, examples, and READMEs switched to the Unix epoch at the Royal Observatory, Greenwich. - Known issue, not yet fixed:
oxiephemeris-lodpulls inquick-xml 0.37.5transitively viaoxigraph, carrying two HIGH-severity RUSTSEC advisories (denial-of-service via crafted XML). No upstream fix exists yet — see Tips.
Tips
- Query the live vocabulary right now, no install required.
sparql.cooljapan.techis already serving OxiEphemeris’s ontology:curl -G 'https://sparql.cooljapan.tech/sparql' \ --data-urlencode 'query=ASK { <https://cooljapan.tech/ns/oxiephemeris/concept/sign/Scorpio> a <http://www.w3.org/2004/02/skos/core#Concept> }' \ -H 'Accept: application/sparql-results+json' - Switch to
--format turtle|ntripleson every chart-family command instead of the legacy--jsonflag — one flag now coverschart,synastry,transit,progress, andcompositeuniformly. - Generate the vocabulary standalone with
oxieph vocab --part ontology --format turtleand feed it straight into your own triple store — it needs no DE kernel at all. - Shift to a sidereal zodiac with
--sidereal lahiri(orfagan-bradley/krishnamurti/raman/j2000-zero) onpos/houses/chart— the CLI/astro path agrees with the independently-implementedoxiephemeris-compatpath to under 1e-6° on the same epoch and site. - Don’t expose
oxieph-sparqldto untrusted networks, and don’t--loaduntrusted RDF/XML yet. The transitivequick-xmlRUSTSEC advisory has no upstream fix; the publicsparql.cooljapan.techinstance sidesteps this entirely by running OxiRS instead of this binary. - Pin your toolchain to 1.89+ if you build with
--all-features. The new RDF/SPARQL stack (oxigraph/oxrdf/oxttl) raised the workspace MSRV from 1.81; the non-RDF crates alone would still build on 1.81.
This is the foundation
OxiEphemeris is COOLJAPAN’s astrology/ephemeris and Linked-Open-Data computation layer — a clean-room JPL DE/SPK reader, an IAU 2006/2000A frame pipeline, a full astrology layer, and now an RDF vocabulary with a SPARQL endpoint, all computed once and reused everywhere. It’s still a young, standalone project — 0.1.0 shipped one day before this release, on 2026-07-10 — and honestly, there’s no ecosystem consumer list to report yet: a scan of every other COOLJAPAN project’s Cargo.toml turns up nothing depending on it so far. Its own dependency graph also reaches outside COOLJAPAN for one piece: the RDF/SPARQL stack (oxrdf, oxttl, oxigraph, oxhttp) is the independent, third-party Oxigraph project — it shares the “oxi” prefix by coincidence, not affiliation, and is always built with default-features = false so it never pulls in RocksDB.
One real thread already connects OxiEphemeris to the rest of the stack, though: the live public SPARQL endpoint at sparql.cooljapan.tech doesn’t run oxiephemeris-lod’s own oxieph-sparqld binary at all — it’s served by OxiRS, COOLJAPAN’s own SPARQL engine, behind CloudFlare, preloaded with OxiEphemeris’s oxa:/oxc:/oxs: vocabulary. oxieph-sparqld, built on the third-party oxigraph, remains the self-hostable alternative for anyone who wants to run their own instance instead of querying the shared one.
Repository: https://github.com/cool-japan/oxiephemeris
Star the repo if you want an ephemeris engine you can read start to finish, check against JPL’s own test vectors, and query with SPARQL instead of scraping stdout.
The era of ephemeris software that’s either a black-box C core with a license negotiation attached, or a browser reimplementation with its own separate bugs, is over. Pure Rust astrology — clean-room, verified against independent oracles, and now queryable — is here, fast, safe, and sovereign.
— KitaSan at COOLJAPAN OÜ
July 11, 2026