CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Development

npm install          # one-time: pulls Vite, Three.js, ESLint, Prettier
npm run dev          # Vite dev server with HMR (default: http://localhost:5173)
npm run build        # production build into dist/
npm run preview      # serve the built dist/ for verification
npm test             # node --test test/*.test.js (unit tests, no bundler)
npm run lint         # ESLint
npm run format       # Prettier (rewrite in place); format:check for CI

Vite handles dev/prod parity: the same module graph the dev server serves with HMR is what gets bundled and tree-shaken into dist/ at build time. Three.js and its addons are resolved from node_modules/three (no CDN). Locale JSONs and texture images are registered via import.meta.glob so they participate in content-hashing.

Tests run on raw Node 20+ — they cover src/physics/ and src/data/, neither of which imports Three or Vite-specific APIs. To run a single test file: node --test test/physics.test.js.

glab is required for the MR and release workflow (glab mr create, glab release create). Install via brew install glab on macOS or from the official releases elsewhere.

Architecture

docs/architecture.md is the canonical overview: the conceptual pipeline (scientific Kepler model → reprojected scale model → scene → vcams → UI → animation/voyages), the file-tree layout, and the build-level decisions. docs/camera.md is the camera cookbook; docs/storytelling.md is the cross-axis tween convention. The section below is the per-module operational catalog those overviews point back to — one line per module, with non-obvious gotchas called out.

Shared modules (src/)

src/data/ — astronomical data, pure & Node-testable:

src/physics/ — canonical math, no Three / Vite, Node-testable:

src/camera/ — generic Cinemachine-style layer; writes only a duck-typed controls.target:

src/textures/loader.js (async photographic-map loader, procedural fallback) + procedural.js (deterministic Canvas2D fallback textures).

i18ni18n.js (runtime: t, setLang, getLang, objectName, onLangChange, fmtNumber, mountLangToggle, applyLangToLinks, applyPageMeta, ready; resolution ?lang=→localStorage→navigator→fr), i18n-url.js (pure rewriteHrefForLang, split out for Node tests), locales/{fr,en}.json (dot-path translation tables).

src/ui/sidebar.{css,js} (shared sidebar base + initSidebar()), view-bootstrap.js (bootstrapView(...) collapses the per-view boot dance), tabs.js / mode-switcher.js (generic mountTabs / mountModeSwitcher), panel.css / solar-system-overlays.css (panel-system / HUD-overlay styles).

src/widgets/ — cross-view UI:

src/voyages/ — voyage engine:

src/views/ + roots — views/{solar-system,galaxy,universe}.js (self-mounting per-page modules), populations.js (asteroid-population Three.js renderer, buildPopulations), version.js (single VERSION export).

src/solar-system/solar-system.html’s state, scene, vcams, panel:

Design rules

For adding a new view, see the step-by-step in docs/architecture.md.

Workflow

See CONTRIBUTING.md for the contributor workflow: git flow, issue labels, commit-message style, docs-match-code rule, release process, deployment trigger. Follow it exactly — the rules about self-assigning, opening the draft MR before writing code, and treating ready MRs as frozen are the ones most likely to bite if skipped.

Language note

UI strings are in French. Code, comments, and documentation are in English.

← Astrarium