Go
go get and go — embedded WebAssembly, no cgo, cross-compilation preserved.
For: developers
Installation
go get github.com/x-haose/x-iztro/go/iztroThe package embeds a WebAssembly module compiled from the core library (wasm32-wasip1) and calls
into it through wazero, a runtime implemented in pure Go.
Which means: no cgo, no Rust toolchain on the machine, and cross-compilation still works. wazero's compiler backend covers amd64 and arm64 only; other architectures fall back to the interpreter — slower, same results.
Concurrency and cold start
A single wasm instance cannot be used concurrently, so the package keeps an instance pool (capped at
GOMAXPROCS). Calls from multiple goroutines are not serialized against each other and run in
genuine parallel.
The first call has to compile the wasm module. The compiled artifact is cached on disk (under
os.UserCacheDir()), so only the very first run costs ~200ms; after that the first call in each
process costs ~30ms. If you want a service's first request to take the hot path, call
iztro.Warmup(ctx) once at startup. On the hot path a chart — including JSON encoding, decoding and
memory copies — is on the order of 0.5ms.
Charting
package main
import (
"fmt"
"log"
"github.com/x-haose/x-iztro/go/iztro"
)
func main() {
// the fifth argument is the chart language; "zh-CN" is what the other
// pages default to, "en-US" gives an English chart
chart, err := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageEnUS, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(chart.SolarDate) // Gregorian date
fmt.Println(chart.LunarDate) // lunar date
fmt.Println(chart.ChineseDate) // the four pillars
fmt.Println(chart.Time, chart.TimeRange)
fmt.Println(chart.Sign, chart.Zodiac)
fmt.Println(chart.Soul, chart.Body) // soul star, body star
fmt.Println(chart.FiveElementsClass)
}2000-8-16
二〇〇〇年七月十七
geng chen - jia shen - bing woo - geng yin
Tiger hour 03:00~05:00
leo dragon
rebel scholar
wood 3rdReading the output
LunarDate is the one field that stays in Chinese in an English chart: the lunar date is written
with Chinese numerals, and 二〇〇〇年七月十七 is the 17th day of the 7th lunar month, 2000.
ChineseDate is the four pillars romanized in pinyin — geng chen is 庚辰, bing woo is 丙午.
The last argument is a *Config; pass nil for the defaults. gender and language are the named
types iztro.Gender / iztro.Language (iztro.GenderFemale, iztro.LanguageEnUS; string literals
still work). Chart from a lunar date with ByLunar: where BySolar takes fixLeap, this takes a
three-way iztro.LeapMonth (NotLeapMonth / LeapMonthKeep / LeapMonthFixed), so one argument
says how the leap month is handled:
iztro.ByLunar("2000-7-17", 2, iztro.GenderFemale, iztro.NotLeapMonth, iztro.LanguageEnUS, nil)Every entry point has a *Context variant (BySolarContext, ByLunarContext and so on), where
ctx cancels the wait for a pooled instance.
Error handling
Failures always come back as *iztro.Error carrying a machine-readable Code; match them by
category with errors.Is:
_, err := iztro.BySolar("2000-13-1", 2, iztro.GenderMale, true, iztro.LanguageEnUS, nil)
if errors.Is(err, iztro.ErrInvalidDate) {
var e *iztro.Error
errors.As(err, &e)
fmt.Println(e.Code, e.Message)
}invalid_date invalid solar date '2000-13-1': month must be within 1-12See Error handling.
Next
The example above only touches the charting entry point. The full API — locating the twelve palaces, star predicates, flying stars, horoscopes, the star-placement module, data tables and translation — lives under Go API, where every exported function, type and method has its own entry with real run output and edge-case notes.