Introduction
Turn a birth date and hour into a complete Zi Wei Dou Shu chart, and into text a language model can read. A Rust core, callable from Rust, Python and Go, matching JS iztro field for field.
For: developers · Zi Wei enthusiasts · product and decision makers
Turn a birth date and hour into a complete Zi Wei Dou Shu chart, and into text a language model can read in one call — let the library get the chart right, let the AI do the reading.
One call produces this text. Paste it into any language model and start asking questions:
=== Basic Info ===
Gender: female
Solar Date: 2000-8-16
Lunar Date: 二〇〇〇年七月十七
Chinese Date: geng chen - jia shen - bing woo - geng yin
Time: Tiger hour (03:00~05:00)
Zodiac Sign: leo
Zodiac Animal: dragon
Soul Palace Branch: woo
Body Palace Branch: xu
Soul Star: rebel
Body Star: scholar
Five Elements Class: wood 3rd
Birth-Year Mutagen: sunA, generalB, moonC, fortunateD
=== Palaces ===
--- wealth ---
Stem-Branch: wuyin
Decadal: 43-52
Age Fortune Years: 9, 21, 33, 45, 57, 69, 81, 93, 105, 117
Twelve Gods: dissipated, gossip, sorrowing, varied
Major Stars: general([+1])[B], minister([+3])
Minor Stars: horse
Adjective Stars: considery, senior, ageless, psychic, gourmet, gloomy, upset
(the other eleven palaces omitted)Whether a chart is correct has one hard standard here: zero field-level divergence from JS iztro v2.5.8, held by 716,314 golden test cases.
The core is written in Rust and exposed to higher-level languages through three bindings:
Rust
A native crate with strongly typed, zero-copy structs
Python
A native PyO3 extension with a typed dataclass API
Go
Embedded WebAssembly on a pure Go runtime, no cgo
The problem it solves
Charting Zi Wei Dou Shu looks like table lookup, but it drags in a chain of easily botched calendar and school-of-thought details: handling leap months in the lunar calendar, whether the late Zi hour belongs to today or tomorrow, whether the year's stem and branch turn over on lunar New Year or at the Beginning of Spring (立春, the solar term around 4 February), how nominal age (虚岁, the East Asian reckoning that starts at 1 on the day of birth) increments, and how mutagen tables differ between schools. Decide any one of them differently and you are no longer looking at the same chart.
The most complete open-source implementation in the community is iztro, written in JavaScript — but it only runs on a JS runtime. x-iztro ports that logic to Rust in full, so servers, data-analysis scripts, command-line tools and mobile apps can all work from the same charts.
Relationship to iztro
x-iztro is a port of iztro v2.5.8, not a reinvention. Wherever iztro has a feature or a data table, the two must agree field for field — a line held by 716,314 golden test cases. See Accuracy.
Features
One call to text an AI can read
The semantic text projection (to_text) is built in: project a chart or a horoscope into the natural-language text shown above and hand it straight to a language model, with no need to assemble a chart description yourself. See Semantic text.
Complete charts and horoscopes
Natal chart, decadal, age, childhood, yearly, monthly, daily and hourly scopes: palaces, stars, mutagens and surrounded palaces are all reachable across six levels. Yearly adjective stars, the twelve Sui-qian gods, the twelve Jiang-qian gods, the twelve Boshi gods and the twelve Changsheng gods are all present.
Configurable schools and boundaries
The six switches on Config cover every point practitioners actually disagree on: the year
boundary, the horoscope boundary, the nominal-age boundary, where the late Zi hour belongs, the
algorithm school (default / Zhongzhou) and the charting perspective (heaven / earth / human plate).
The mutagen and brightness tables can also be replaced wholesale. The defaults match JS iztro;
details on Config in depth.
Six chart languages
Simplified Chinese, Traditional Chinese, English, Japanese, Korean and Vietnamese. Switching the chart language only swaps the translation — the computed result is unaffected.
A Chinese chart and an English chart answer the same
For developersStar and palace names read differently in each chart language, but every entity also carries a stable key. The Python enums and Go constants are built on those keys, so a check like "does the Soul palace hold Ziwei?" is written the same way and yields the same answer on a chart in any chart language. See The key contract.
One minute in
from x_iztro import Astro
astro = Astro()
# 2 = hour index; index 2 is the Tiger hour, 03:00-05:00.
# language defaults to "zh-CN"; pass "en-US" for an English chart.
chart = astro.by_solar("2000-8-16", 2, "female", language="en-US")
soul = chart.palace("soulPalace") # the Soul palace
print(chart.five_elements_class, chart.soul, chart.body)
print(soul.name, soul.heavenly_stem + soul.earthly_branch)
print([s.name for s in soul.major_stars])wood 3rd rebel scholar
soul renwoo
['emperor']Full installation and examples for all three programming languages are on Getting started.
Where to read next
Using it without writing code
What it can do, where it fits, and what to hand your engineers
Getting started
Install it and produce your first chart
Zi Wei concepts
Readable without any background in the art: what a chart is made of and what each field means
Rust API
Function signatures, types and methods of the core library
Python API
Every entry of the typed dataclass API
Go API
Every exported function, type and method
Data model
The type and meaning of every field — the contract shared by all three programming languages
Accuracy
How 716,314 golden cases keep the output identical to iztro