Zeitgeber – 12 o’clock is almost never noon
An astronomically correct sun clock as an offline PWA: it shows the gap between legal time and the real position of the sun – fully local, no backend, with a UI-free calculation layer.

Almost every clock knows your time zone, but not your location. Yet legal noon can sit well away from the real solar noon, depending on where you are and the season. Zeitgeber shows both sides: social time and the actual position of the sun – and the gap between them. Concept, architecture and implementation are entirely mine.
Tech stack: TypeScript (strict) · Vite · PWA · satellite.js · React Native/Expo · Vitest
The idea: the offset
Two quantities can be brought together on one dial: the solar time offset (legal noon vs. real culmination – pure physics) and social jetlag per the Munich Chronotype Questionnaire (four times are enough). Late chronotypes living on the western edge of a time zone experience both effects additively. Zeitgeber shows this as the combined total offset – on a single 24-hour dial with continuous twilight zones.
Architecture: three axes, one bus
The core is a UI-free calculation layer of pure functions: sun (NOAA algorithm), moon (Schlyter), planets (Keplerian elements), stars and satellites (SGP4). On top sit three separate axes – providers (what is in the sky), views (how it looks) and capabilities (modules such as solar yield or outdoor). An object-bus aggregates the active providers and isolates errors per module. A new provider automatically appears in every view.
A side effect: the web PWA and the native app (iOS/Android) share the same engine – no copy of the astronomy logic.
Correctness before features
Calculations are tested against reference values and physical invariants, such as Polaris altitude ≈ geographic latitude or the maximum elongation of the inner planets. A real-world bug: time readouts must follow the time zone of the selected location, not the device – otherwise “time travel” is wrong. There is deliberately no astrology or solunar folklore.
Offline and without a backend
No account, no server, no trackers. Location and inputs stay on the device, and a service worker makes the app work offline. Optional modules are off by default – if you configure nothing, you see a calm dial. The code is open source (AGPL-3.0): github.com/darkjive/Zeitgeber.
What I take away
A clean split between calculation and presentation pays off twice: it makes testing easy and allows new platforms without rewrites. And restraint is a feature – breadth should reveal itself when someone looks for it, not before.