Skip to content

Repository files navigation

starwheel

test npm

A real-time sky map for your terminal.

npx starwheel

It computes the positions of the stars, planets and the Moon for your location and the current minute, then draws the sky in braille.

No network. No API. No image. It is the actual sky, calculated.

   ⠈ ⠠ ⠶⠁Pollux⠄ ⠐ ⠈⡀   ⠄ ⡁ ⠈⠅⡀⡠⠦⠤⠂ ⢀⠂    ⠐   ⢁ ⠠   ⠂                ⠠⡢ M 33    ⠄     ⠠ 
      ⢀  ⢁   ⣠⣴⣤⡂ ⡒  ⠁⠐⠠   ⢀⢠⠈⡀⡅⠠⠑⡀⠠ ⠁        ⠐⠄⠑        ⢀     ⠁  ⠈      ⠄     ⠐       ⠂
          ⠠ ⠰⣿⣿⣿⡇⠈⢔⠐Moon  ⣀⠂ ⡈⠈⠐⠚⢀        ⢀         ⠂    ⢄⠐     ⡀         ⠐  ⠠⠄⠈       ⣈
          Gemini⠁ ⠡ ⠂⢕⠊⠡⢁⡄ ⣠⠐ ⠂    ⠄            ⡀          ⠁⠐ ⠂⠠ ⡤⠐        ⢀            
     ⠂    ⢀⠁ ⠈⡊⣁⢂⠁ ⢄⠄⢈⠄⠁  ⠂⠐⠈⢀ ⠄⠠  ⡀⠈ ⠄⠂ ⠠   ⡀ ⠈⠋ M 45  ⡀         ⠐⠰                    
          ⠠     ⠂⠄ ⠐ ⠄  ⡈⠅⠌   ⡀⠁⠐ ⢄    ⠐ ⡀ ⠂         ⠈⠂ Aries      ⠈                    
               ⠠ ⢠⠋ ⠢  ⢣⠄⠇⠄ ⠐⣠ ⠈  ⡀⡈ ⠂⠠⣠⣄⣼⣂                             ⠁               
       ⠈     ⢁⠊ ⡒⡉     ⢁⠁⡀ ⠄  ⠄    ⠁⠤⠂ ⢀⠁Aldebaran ⡀                                    
       ⠐⠆    ⠂   ⢖⠆NGC 2264  ⣠      ⢨  ⢀      ⠁⠐ ⠄⠠⢀⡀     ⡀⠤ ⡀   ⡀    ⠄       ⢀  ⢀      
     ⣀    ⢀⠘ ⠂  ⠅ ⡐ ⡄⠄⠔  ⢨⡤⢀⠁⡀⠂⣀⢀ ⠂⠈ ⣑     ⠉   ⢀ ⠄⠈ ⡉   ⢈     ⠍        ⡀ ⠄              
⡀    ⠉ Procyon⢀ ⢀ ⠐⡷⠂⠌⠐⠁  ⠐Betelgeuse⠆       ⠈⠂    ⠄ ⡀  ⢤ ⡀⢀ ⠃       ⡀                  
         ⠆⠢⢀ ⠐⠉⡈⠈⢠   ⠁    ⠂⢁⠄ ⠨⠂ ⠁ ⠠⠔             ⡐        ⠈⣁      ⠁                  ⠂ 
⠂       ⠔ ⠈⢀ ⢁  ⠐⠂  ⢂⠐      ⣢⠬⠃⡈        ⠈         ⠁         ⠈ ⠄⢀                 ⠂      
⠐        ⠐ ⡤⠡⠠ ⣈⠑⠐ ⡀ ⠁⡀ ⠈   ⠄⣀ ⠈⠄ ⡀⠠⢀⠂⠃⠘⠂⢀     ⠁   ⡀            ⠁⢀     ⠂                
         ⠐ ⠄⡃⠒⡀ ⠐⠠⠠⠅  ⠂    ⠐⠠⠱⠁M 42⠄       ⠢⠆                      Cetus                
    ⢀ ⠄ ⠐⡀⢀  ⠢  ⢁       ⢀  ⠚     ⠋⠁Rigel   ⠠ ⠂   ⠆⠐⠂⠐⠈⠂⠈ ⠉⢀         ⠐⣀⠠ ⠄⠐⠈⠁⠐⢀⡀⢀ ⡀⢀ ⠄⠠ ⠄
    ⠈ ⠒⠠⢀⢀⣀ ⡀ ⠠⠠      ⡀         ⠄⠊ ⠐   ⢁      ⠡ ⠚          ⢄⠁ ⠐       ⠄            ⠁   ⠐
    ⠠⠐⣀ ⠂⠁  ⢂ ⡲⠂ ⠈     ⠐⡀⠈ ⠁     ⠄                         ⠠ ⠐        ⢐   ⠂          ⡀⠁ 
  ⡄⠰ ⠥⡀⡀  ⠈⠠ ⠁⠸⠄⢺⠖Sirius      ⠉    ⢀   ⠄       Eridanus    ⠆            ⠁⠐ ⠂⠠ ⡀    ⠠    
 ⢀⣄  ⠐ ⡈ ⠠⠠⠃⠁⠈⠠⡄⠁ ⠁       ⠐ ⡀ ⠐ ⠂ ⠠             ⡀ ⠰⠠ ⡆⢀  ⠐⠂        ⠄           ⠈ ⠁⠘⠁    
⠅     ⢀⠁⠁⡈   ⡀⠨    ⠤                          ⠁⠆⠈⠁     ⠈⠊          ⠈                    
⢄⡐⠰  ⠄⠠⠉⡂⠠⢨⢅ ⠈⠂⠈             ⠐⠕ M 4       ⢀ ⠂⠈                                        ⢀⣀
2026-12-24 22:00 GMT  51.48°N 0.00°W  facing S 180° alt 42° fov 115°  276 stars  night

84 kB download, one dependency — skymaths, my own, and itself dependency-free. Nothing to configure but your location.

starwheel --find saturn        # point the view at something
starwheel --at 2026-12-24T22:00

Click any object for its magnitude, altitude and bearing. hjkl or the arrows to look around, +/- to zoom, [/] ,/. </> to step time by ten minutes, an hour or a day.


Why braille

Unicode braille addresses 2×4 dots per character cell, so an 80×24 terminal is really a 160×96 canvas. That is what separates a rendering from ASCII art.

It also turns out the dots are very nearly square: a character cell is about 1:2, and dividing it into 2 columns and 4 rows gives dot spacing of w/2 across and h/4 = w/2 down. Measured in Ubuntu Mono 11 — cell 8.00 × 17px, dots 4.00 × 4.25px, an aspect of 1.062. Constellations come out the right shape almost for free.

The Moon, with its real phase

    ⠂          ⠂⢤⡀        ⣦⣤⡀       ⣠⣦⣤⡀      ⣠⣤⣦⣤⡀      ⣠⣤         ⣠⠄
       ⠂        ⠈⣿⡆       ⣿⣿⣿⡆     ⢰⣿⣿⣿⣿⡆    ⣾⣿⣿⣿⣿⣿⡆    ⣾⣿⣿        ⣾⡏
       ⡈         ⣿⡏       ⣿⣿⣿⡏     ⢸⣿⣿⣿⣿⡏   ⠈⣿⣿⣿⣿⣿⣿⡏   ⠈⣿⣿⣿⡇      ⠈⣿⡇
    ⡀          ⡀⠼⠋        ⡿⠿⠋       ⠻⡿⠿⠋     ⠈⠻⠿⡿⠿⠋     ⠈⠻⠿⡇       ⠈⠻⠄⡀
   new      crescent    first qtr    gibbous       full       last qtr   crescent

The lit side needs no waxing/waning flag: it is wherever the Sun is. The disc is rotated until the limb direction is +x, so "lit" simply means "right of the terminator" — automatically correct for a waxing crescent, a waning gibbous and everything between.

The terminator is an ellipse, half-width R·|1−2·illum|, narrowing to a line at half moon. A straight-line terminator passes a glance and is 10–20% wrong in the crescents. There is a test that measures the drawn lit area against the ephemeris fraction and requires them to agree within 6%.

Planets, as discs when you zoom in

                     ⠠⣧⡀        Venus
                      ⠻⣿⣶⣤⡤
                        ⠈
                    ⢠⣶⣷⣦
                   ⠉⠹⣿⣿⡿⠈⠁ Saturn

Venus at 38″ and 30% lit — a genuine crescent, which is the most surprising thing in a small telescope. Saturn at 19″, rings hinted either side.

Planets are relatively true to each other but on their own scale, because Jupiter is 32″ across and the Moon is 1908″ — one shared scale gives you either an absurd Moon or invisible planets. They stay capped below the Moon so the size ordering holds, and below two dots they fall back to a point, so at a wide field they are stars among stars and only become objects when you zoom in.

Which planets show a phase falls out of the maths rather than being special-cased: only Venus, Mercury and Mars are ever meaningfully less than full from Earth. The outer planets are lit from behind us and draw as correct round discs for free.

Keys

h j k l or arrows look around
n e s w face a cardinal point
+ - zoom
, . step time by an hour
r back to now
f constellation figures on/off
g the sky below the horizon
q quit

You can look anywhere. Left and right wrap, as you would expect — but so does up and down. Keep tilting and you go over the zenith, down the far side, under the nadir and back to where you started. Thirty-six presses of k at ten degrees is a closed loop, exactly.

Going over a pole flips you rather than stopping dead: the altitude reflects off 90° and the azimuth swings 180°, which is what happens if you keep tilting your head back. The horizon stays level through the crossing rather than the view rolling over — more literally correct, much worse to use, and every planetarium makes the same call.

The sky below the horizon is drawn by default, dimmed, because otherwise half of that loop is blank. From London, straight down shows 47 Tuc, the Magellanic Clouds, ω Centauri and the Southern Cross — none of which ever rise there. Above the horizon brightness still comes from real atmospheric extinction, so stars fade as they set; below it everything is flat and dim. That difference in texture is what keeps the horizon readable with sky on both sides of it. g toggles it, --no-below starts without it.

starwheel --spin        # a full 360° turn on its own, for asciinema

Click a star

Click anything drawn — a star, a planet, the Moon, a deep-sky object — and a card appears with what is known about it. Escape clears it, the mouse wheel zooms.

Sirius
magnitude  -1.44
position  14.1° up, SE
Moon
type  moon
position  48.2° up, ESE
lit  99% waning
distance  357,285 km

All of that is computed — from the catalogue and the ephemeris, with no network and no third-party code. It is there the moment you install, and it is the part worth having.

Optionally: ask a local model

If — and only if — you have ollama running, pressing a adds a few sentences of context underneath the card. starwheel does not depend on it: with ollama absent the key is never offered and everything above works exactly as it does here.

ollama pull qwen3:1.7b     # ~1.4 GB, once

If you already run ollama but not that model, the smallest one you do have is used instead. Set STARWHEEL_MODEL to choose.

The model is never the source of a fact. Every number — position, magnitude, distance, phase — is computed by skymaths and handed to the model in the prompt. It is asked only to say what is interesting about an object it has been told about. Ask a model how far away Betelgeuse is and it will produce a confident number that may be wrong by a factor of two; tell it "this star is magnitude 0.45 and 41° above your south-eastern horizon" and the facts on screen stay correct whatever it says.

Everything runs on your machine. Nothing leaves it, and there is no API key.

The model is small on purpose. Measured on a 4-core ultrabook CPU with the real prompt:

model first word complete
qwen3:1.7b 1.6s 4.5s
qwen3:8b 5.5s 19.9s

Three times faster, and for a two-sentence card the answers are of a piece — the 8B says "red supergiant" where the 1.7B says "distinctive red color and large size", which is not worth fourteen seconds. The answer streams in either way, so you can carry on panning while it fills.

The zodiac, and the thing nobody mentions

z, or --zodiac, draws the ecliptic — the line the Sun follows — divided into the twelve 30° signs. It is worth having on for a moment even if you have no interest in astrology, because it explains a pattern you can otherwise only notice: the Moon and every planet are always strung along that same line, because that is the plane the solar system is flat in.

The status line then says which sign the Sun is in, and it will agree with any newspaper — a sign is a 30° slice of ecliptic longitude measured from the vernal equinox, so the March equinox is 0° Aries and the December solstice is Capricorn, by definition.

What it will not agree with is the sky. The signs were fixed about two thousand years ago, when they lined up with the constellations of the same name. Precession has since dragged the equinox backwards by roughly a whole sign, so on 9 August the Sun is in the sign Leo while sitting in the constellation Cancer. starwheel draws both, and they visibly do not line up.

Options

starwheel --lat 51.5 --lon -0.1        your location; north and east positive
          --at 2026-12-24T22:00        a specific time, local unless it ends in Z
          --az 180 --alt 45            where to look
          --fov 110                    degrees of sky across the width
          --mag 5                      faintest star drawn
          --labels 0|1|2|3             constellation naming, 0 = none
          --moon 9                     fix the Moon's radius in dots
          --no-figures --no-color
          --once                       one frame and exit, for piping

Set your location. It is the one thing that cannot be guessed — latitude decides which stars ever rise, longitude sets the time they do it, four minutes per degree. STARWHEEL_LAT and STARWHEEL_LON work too. Without either it uses Greenwich and says so in the status line, so a wrong location is visible rather than silently wrong.

What it draws

1627 stars to magnitude 5, at their true positions and B−V colours, precessed to date. Magnitude is drawn as size as well as brightness — a braille dot cannot grow, but a star can occupy several, and only seven stars in the whole catalogue reach the largest tier.

89 constellation figures, dotted and rank-filtered. Solid lines for all 89 put 545 lit dots against 186 of star — guide lines outweighing the things they guide you to. Now it is 1.15:1, and a test pins it there.

The Milky Way, as a stipple cloud of 2407 points baked from five nested isophote outlines. Filling a polygon per frame in a terminal is not cheap; precomputing the fill means the galaxy costs the same as a few hundred extra stars.

32 deep-sky objects — the Pleiades, the Orion Nebula, Andromeda, the Magellanic Clouds — drawn as open diamonds. A filled blob is a star; these are emphatically not stars, and at four dots there is no honest way to tell a globular from a galaxy, so no attempt is made. The name carries the rest.

The Sun, and the truth about whether you could actually see any of this. The Sun's altitude is computed whether or not it is drawn, and the status line says daylight, civil twilight, nautical twilight, astronomical twilight or night by the standard definitions. A planisphere should show you the chart at noon — it should not imply the stars are out.

A horizon and compass in the observer's frame — at an azimuth, not an RA and Dec — so they stand still while the sky turns past them.

Atmosphere: Kasten–Young airmass and real extinction, so stars fade as they set and the horizon gains depth.

Accuracy

Naked-eye accurate, not an ephemeris for occultation timing. Planetary positions come from mean orbital elements with secular rates — arcminutes, not arcseconds, which is far below one braille dot at any field of view. Precession, sidereal time, phase-angle magnitudes and airmass are exact.

The astronomy lives in skymaths, a dependency-free library with 40 invariants, shared with TerraFirma, which draws the same sky over the GNOME desktop. One implementation, two renderers.

Credits

Star data from d3-celestial by Olaf Frohn (BSD 3-Clause), which compiles positions from XHIP (Anderson & Francis 2012), constellation figures from the IAU, the Milky Way outline from José R. Vieira, and deep-sky objects from the Saguaro Astronomy Club. See NOTICE.md.

MIT licensed.

About

A live planisphere in your terminal. Real star positions for your location and clock, drawn in braille.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages