starmap-tonight Svelte Themes

Starmap Tonight

Single page almanac for tonight's sky

StarMap Tonight

A single-page almanac for tonight's sky. It answers one question — is it worth going out tonight? — by combining real ephemeris math with weather data and a transparent scoring rule, then drawing the result as a chart you can read at a glance.

Most stargazing apps show you four widgets and leave you to do the cross-referencing in your head. This one commits to a number.

What it does

Three views, all reading from the same underlying data so the moon that's visible on one page is the moon that's visible on the others:

  • Tonight — the dashboard. A 0–100 score with a one-sentence verdict that cites the two factors actually moving the number, plus a sky chart, moon panel with phase, a twilight readout, and a strip of the next seven nights with their own scores and per-hour cloud sparklines.
  • Sky chart — the planisphere full-screen with a time slider that scrubs through the night, so you can watch Orion roll west as the hours pass.
  • Point at sky — a gnomonic "looking up" view. Drag to aim, scroll to zoom, slider the same night. Atmospheric extinction dims stars near the horizon, the brighter ones twinkle (subtly), and the sun renders if you scrub past sunset.

The Tonight Score combines four factors with named deductions:

  1. Dark-window length and class. Does the sky reach astronomical dark at all? Polar summers and short nights are charged appropriately.
  2. Cloud cover averaged across the dark window. Hourly resolution from Open-Meteo.
  3. Moonlight — illumination integrated over how much of the dark window the moon is actually up. A 50% moon that sets at midnight isn't the same as a 50% moon up all night.
  4. Humidity. High humidity dulls transparency even when there are no clouds. Attenuated when clouds already account for the moisture in the sky.

Every deduction is shown alongside the score with its delta and a short reason. Hover any star, planet, deep-sky object, the moon, or the sun on any of the three views and you get a tooltip with name, magnitude, and a brief note; click it to open the Wikipedia article.

What's in the chart

Hand-curated and consistent across all three views:

  • 125 stars across 30 constellations, with the canonical IAU stick figures — the Big and Little Dippers, Cassiopeia's W, Orion, Cygnus's cross, Hercules's keystone, the Cepheus house, Lyra's parallelogram, Delphinus's Job's Coffin, the Southern Cross. Coordinates are J2000, cross-checked against Stellarium.
  • 28 deep-sky objects — every Messier showpiece (Andromeda, Orion Nebula, Pleiades, Beehive, Ring, Dumbbell, Whirlpool, Sombrero, Pinwheel, Bode's, Hercules Cluster, etc.) plus the Magellanic Clouds, Omega Centauri, Carina Nebula, Coalsack, and the Pillars-of-Creation Eagle Nebula.
  • All seven solar-system planets, with elongation-aware visibility so Mercury isn't flagged when it's buried in solar glare.
  • The moon, with a real phase glyph (terminator drawn from the computed phase angle) and its rise/set/illumination.
  • The sun, when above the horizon — only on Point at sky, since the other two views are explicitly "tonight."

The catalogue lives in src/lib/astronomy/. Each star and DSO carries the Wikipedia title for the click-through; the schema is small and easy to extend.

Why these choices

A few decisions that aren't obvious from the code:

Astronomy library. astronomy-engine (Don Cross) is the same library that backs several serious amateur tools. VSOP87 / NOVAS-style algorithms with arcsecond accuracy, not the textbook sin/cos approximations. Planet positions agree with JPL Horizons to a few arcseconds.

Hand-curated catalogue. The full HYG database is ~9 000 stars and looks impressive for one screenshot. After that it's noise. 125 stars covers every constellation people learn by name, renders in under a millisecond, and stays legible at any zoom. The deep-sky list is the same kind of choice — the brightest 28 objects rather than every Messier labelled in the same dim grey.

Score weights. Tuned to my own observing intuition: cloud cover dominates, then darkness class, then the moon, then humidity. The weightings live in tonight-score.ts as plain functions — treat them as a starting point, not an oracle. The point of the score is that it's defensible, not that it's correct in some absolute sense.

Two projections for two views. The planisphere uses a stereographic projection from the zenith — that's how a paper sky chart works when held overhead, with north up and east on the left. The Point at sky view uses a gnomonic projection from the current view direction, which is the natural projection for "look through a window at the sky": straight lines on the celestial sphere stay straight on screen.

Two fonts, no design system. Spectral for prose and JetBrains Mono for numerical readouts. The mono font is doing real work — font-variant-numeric: tabular-nums slashed-zero lines up digits in the readouts so they scan like an instrument panel rather than a page of text.

Data sources

  • Ephemeris: astronomy-engine v2 (Don Cross, MIT).
  • Weather and geocoding: Open-Meteo (CC-BY 4.0). No API key required.
  • Star catalogue: subset of BSC5 (public domain), cross-checked against Stellarium's HIP-keyed positions.
  • Deep-sky positions: the Messier catalogue and a few NGCs (public domain).

Running it

npm install
npm run dev

Build a production bundle:

npm run build
npm run preview

Deploying

The whole app is client-side once it hydrates — there's no per-user server data to fetch — so it's wired up for static export via @sveltejs/adapter-static. npm run build writes a self-contained build/ directory you can drop on any static host.

A GitHub Actions workflow at .github/workflows/deploy.yml builds the site and publishes it to GitHub Pages on every push to main. The included static/CNAME claims starmap.tandra.dev; change it (and the DNS) to point at your own subdomain.

Project layout

src/
├── lib/
│   ├── astronomy/        — ephemeris math, star + DSO catalogues, projections
│   ├── weather/          — Open-Meteo client and an in-memory forecast cache
│   ├── geo/              — geocoding and browser geolocation
│   ├── score/            — the Tonight Score function
│   ├── components/       — Svelte components (charts, dial, glyph, picker, …)
│   └── styles/           — global tokens
└── routes/
    ├── +page.svelte       — Tonight dashboard
    ├── sky/+page.svelte   — Planisphere with time slider
    ├── look/+page.svelte  — Point-at-sky live view
    └── +layout.svelte     — Global styles + nav

License

MIT for the code. Data sources keep their own licences (see above).

Top categories

Loading Svelte Themes