Building a Client-Side Zodiac Calculator: When "Just Use an API" Isn't the Answer
I recently found myself in one of those classic developer rabbit holes. A friend asked me if I knew their Chinese zodiac sign, and instead of just Googling it like a normal person, I thought: "I could build a tool for this." Because apparently I enjoy reinventing wheels. The twist? I wanted it to work entirely in the browser. No API calls, no server, no database. Just a date input and some JavaScript logic. The challenge was figuring out how to accurately compute Chinese zodiac signs, the Chinese lunar calendar year, and the traditional Ganzhi (干支) system without pulling in a massive calendar library. The Problem with Existing Solutions My first instinct was to search for an API. There are plenty of Chinese calendar APIs out there, but they all had issues: Most require API keys and rate limiting Many are Chinese-language only, which is fine for me but not great for a broader audience They're overkill for what should be a simple calculation Some have questionable accuracy for historical dates I also looked at JavaScript libraries like lunar-javascript and chinese-calendar . They're comprehensive, but they're also huge. For a simple "what's my zodiac sign" tool, pulling in a 100KB+ library felt like using a flamethrower to light a candle. The Math Behind the Madness Here's what I discovered: the Chinese zodiac and Ganzhi calculations are surprisingly straightforward if you understand the underlying math. The Zodiac: Simple Modulo Arithmetic The 12 Chinese zodiac animals follow a cycle that aligns with the 12-year Jupiter cycle. The calculation is embarrassingly simple: const ZODIAC = [ ' 鼠 ' , ' 牛 ' , ' 虎 ' , ' 兔 ' , ' 龙 ' , ' 蛇 ' , ' 马 ' , ' 羊 ' , ' 猴 ' , ' 鸡 ' , ' 狗 ' , ' 猪 ' ]; const zodiac = ZODIAC [( year - 4 ) % 12 ]; That's it. The year 4 AD was the first year of the Rat, so everything since then follows a simple modulo pattern. The Ganzhi System: Two Interlocking Cycles The Ganzhi (干支) system combines the 10 Heavenly Stems (天干) with the 12 Earthly Branches (地支