A static web app (plain HTML + JavaScript) that visualises logistic distances between bodies in the solar system for a hard-scifi setting — delta-v budgets, transfer times, propellant / energy costs — rather than raw kilometers. It runs entirely in the browser and is hosted on GitHub Pages.
The goal is to give worldbuilders, players and writers a "subway map" of the solar system where edges are weighted by what actually matters for spaceflight: how much delta-v it costs to get from A to B, how long a realistic transfer takes, and how much propellant that implies for a given drive.
Hard-scifi constraint: no reactionless drives, no magic. Values come from patched-conic / Hohmann approximations grounded in real orbital mechanics.
Spacecraft are defined by exhaust velocity, structural mass, fuel/propellant mass, and payload mass. Delta-v and fuel consumption are derived from this data via the Tsiolkovsky rocket equation.
A node is a location of interest in space — a body (planet/moon/asteroid) surface, an orbit, or a Lagrange point. Orbit nodes for very small bodies (<100m/s dv) are omitted. Only "interesting" lagrange points from the point of view of logistics are included:
- SMercury/SV L1/L2: interplanetary logisitcs hubs
- EM L1/L2: logistical/refueling hub for Earth/Moon transit & interplanetary departures
- EM L4/5: large zone of stable orbit for solar collectors/cities/industrial hubs
- ES L4/5: same as EM L4/5, but much larger. Also mining of Earth trojans asteroids.
- SJ L4/5: same as ES L4/5, but much larger again. Mining Jupiter trojans asteroid (1/5th mass of main belt, icy asteroids)
- JCallisto L1/L2: logistical/refueling hub between Jupiter and rest of solar system
- JGanymede L1: Sits on edge of radiation belt, processing hub for inner-Jovian resources
- Saturn-Tethys L4/5: trojan moons Telesto/Calypso
- Saturn-Dione L4/5: trojan moons Helene/Polydeuces
- Saturn-Enceladus L1: potential harvesting of Enceladus water plumes
- Saturn-Titan L1/2: logistical/refueling hub between Saturn and rest of solar system
- Neptune L4/5: large amount of trojan asteroids, comparable to main belt
A connection is a path of travel between two nodes, including delta-v, transfer time, launch windows and aerobraking possibility.
We assume optimal delta-v trajectories (Hohmann transfers) and transfer windows.
Note: delta-v values are sourced either from existing datasets or generated via LLM using napking calculations. Thus values
should be taken with a large grain of salt.
In future would be interesting to investiguate using a real orbit calculator to generate the dataset.
There is no build step and no backend. The page fetches the dataset and transforms it in the
browser, so you just need to serve the docs/ directory over HTTP. Opening index.html via
file:// will not work — fetch() of the dataset is blocked by the browser's same-origin
policy on file://.
# Serve the static site on http://localhost:8000/
python -m http.server 8000 --directory docsThen open http://localhost:8000/. Any static file server works (e.g. npx serve docs).
docs/ # everything the site needs (this is what GitHub Pages serves)
index.html # page shell, styles, legend + controls
build_elements.js # transforms the dataset into Cytoscape elements + value bounds
graph.js # Cytoscape layout, geometry, slider wiring
closest_bodies.js # shortest-Δv "nearest bodies" computation
solar_system_nodes.json # canonical dataset (source of truth + the file the browser fetches)
.nojekyll # disable Jekyll processing on GitHub Pages
The dataset lives in docs/solar_system_nodes.json — a single canonical copy that is also the
file the browser fetches, so there is nothing to keep in sync.
- Plain HTML + ES modules, no build tooling.
- Cytoscape.js + the fcose layout, loaded from a CDN.
GitHub Pages serves the docs/ directory directly from the default branch — no build step, no
deploy workflow. Pushing to master publishes. Enable it once under Settings → Pages → Build
and deployment → Source: Deploy from a branch, then select branch master and folder /docs.
Tracked here so the next pass has a starting point. Roughly in priority order.
- All values are precomputed in the dataset. The entire node/connection dataset lives in
docs/solar_system_nodes.json;docs/build_elements.jsonly reshapes it (colours, symmetric-edge dedup, value bounds) for Cytoscape. There is noSpacecraftconcept and no live orbital-mechanics (Tsiolkovsky / Hohmann) — delta-v, transfer times and launch windows are baked into the JSON. The moment per-spacecraft fuel cost or on-the-fly recalculation is wanted, a smallphysics.jsmodule (Tsiolkovsky + mass ratios) called from the page would be the place for it — kept separate from the rendering code, mirroring the math-out-of-views rule inCLAUDE.md.
- HAve a second togglable view type where length is correlated with dv not transfer time.
- Show launch window tag on connectors, with same date formatting as transfer time tag.
- The drag constraint solver has two real holes. It runs 6 Jacobi iterations capping each connected edge at
ideal_len, with no convergence check (a high-degree node like LEO may exit non-converged silently) and no lower bound (nodes can be dragged on top of each other). Either rename to "max-length cap" or enforce a minimum separation too. markOffscreenEdgesonly tests endpoint positions. A coiled edge with both endpoints off-screen can still have its label visible mid-arc, and vice versa. Edge case; revisit only if it becomes annoying.
- No automated tests. The transform in
build_elements.jsand the dataset have no test harness. A small load test that asserts every edge appears in both JSON directions with matching values would already catch the dedup-asymmetry class of bug. - CDN dependency. Cytoscape and the fcose layout load from unpkg at runtime; if reproducible offline hosting is wanted, vendor those scripts into
docs/and reference them locally.
- combined deltav + trasnfer time view -> to view distance as a mix between both
- "logistic cost" view based on fuel/propellant, thrust (surface to orbit needs higher thrust/less efficient), and ship mass (solar sail/solar electric/nuclear propulsion depending on distance to sun)
- mass driver togglable option
- non optimal transfers
- take aerobraking into account (supposing a large efficient ship doing an intercept of target body and dropping a heathielded payload)
- 3d graph