npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

soluna

v2.6.0

Published

JavaScript library for converting between Gregorian (solar) and Chinese lunar calendar dates

Downloads

40

Readme

Soluna

CI

Bidirectional Gregorian ↔ Chinese lunar calendar conversion for JavaScript. Zero dependencies. Single file. Node.js and browser.

Range: 1900–2100  ·  License: BUSL-1.1


what it does

  • solarToLunar — Gregorian → lunar date, zodiac, stem-branch (干支), BaZi four pillars, time period (时辰), festivals
  • lunarToSolar — lunar → Gregorian, leap month aware
  • Month pillar calculated against actual solar term boundaries (not Gregorian month edges)
  • Festival detection: public holidays, Buddhist and Taoist dates, folk traditions, 三娘煞日

install

No npm package yet — copy soluna.js directly into your project.

Node.js

const { solarToLunar, lunarToSolar } = require('./soluna.js');

Browser

<script src="soluna.js"></script>
<script>
  const { solarToLunar, lunarToSolar } = window.Soluna;
</script>

usage

solar → lunar

const result = solarToLunar(2024, 12, 28, 15, 30, 0);
// or: solarToLunar(new Date())

result.lunar
// { year: 2024, month: 11, day: 28, isLeapMonth: false,
//   monthName: '十一', dayName: '廿八', zodiac: '龙' }

result.baZi
// { year:  { stem: '甲', branch: '辰' },
//   month: { stem: '丙', branch: '子' },
//   day:   { stem: '辛', branch: '未' },
//   hour:  { stem: '丙', branch: '申' } }

result.timePeriod
// { name: '申时', zodiac: '猴', period: '15:00-17:00',
//   branch: '申', description: '晡时,又名日铺、夕食' }

result.festivals
// { solar: null, lunar: null, sanniangSha: false }

lunar → solar

const result = lunarToSolar(2012, 4, 7, false, 12, 0, 0);
// pass true as 4th arg for leap month

result.solar
// { year: 2012, month: 4, day: 27, weekDay: '五',
//   time: { hour: 12, minute: 0, second: 0 } }

festival lookup

const cny = solarToLunar(new Date('2025-01-29'));

cny.festivals.lunar
// { name: '春节', isHoliday: true, english: 'Spring Festival',
//   extra: '元始天尊圣旦 弥勒佛圣旦 四始吉日' }

output shape

{
  solar:      { year, month, day, weekDay, time: { hour, minute, second } },
  lunar:      { year, month, day, isLeapMonth, monthName, dayName, zodiac },
  stemBranch: { year, month, day, time },        // 干支 strings e.g. '甲辰'
  baZi:       { year, month, day, hour },        // each { stem, branch }
  timePeriod: { name, zodiac, period, branch, description },
  festivals:  { solar, lunar, sanniangSha }
}

festival coverage

| category | examples | |---|---| | solar (13) | 元旦, 劳动节, 国庆节, 圣诞节 | | major lunar (8) | 春节, 端午节, 七夕, 中秋节, 除夕 | | buddhist (13) | 释迦牟尼佛诞/涅槃/成道, 观音圣旦/成道/出家, 文殊, 普贤, 地藏王, 韦陀, 阿弥陀佛, 达摩 | | taoist (14+) | 玉皇大帝诞, 妈祖, 关帝, 太上老君, 吕洞宾, 王母娘娘, 保生大帝, 文昌, 福德正神 | | folk (8+) | 龙抬头, 头牙/尾牙, 送神/迎神, 寒衣节, 下元节 | | 三娘煞日 | days 3, 7, 13, 18, 22, 27 each lunar month (wedding warning) |


notes

子时 day boundary — 23:00–01:00 (Rat hour) belongs to the next day in traditional Chinese timekeeping. solarToLunar adjusts automatically.

Month pillar — the BaZi month pillar uses the Jie sectional solar term date, not the Gregorian month edge, so dates near the boundary may differ from naive implementations.

Precision — the solar term formula covers 1900–2100 with ≤1 day deviation. VSOP87 would be needed for sub-day precision.


development

make test      # run test suite (node:test, no install needed)
make today     # sanity check: today's lunar + BaZi
make run       # 3-day demo output

See SPEC.md for architecture, algorithm detail, and roadmap.


references


license

BUSL-1.1 — see LICENSE.md