Internals
This page is for contributors working on Rally itself. Application code should treat rally/internal/... as private. These modules have no stability guarantees and can change between releases.
Pipeline
Rally’s codegen runs as a single pass through this pipeline:
gleam.toml config
-> Marmot when configured
-> Proute when proute.toml exists
-> page contract discovery
-> Libero type walk and codec generation
-> Rally generators
-> file output
Rally reads page contracts from authored page modules, Proute owns route params and page dispatch, Libero walks reachable wire type seeds, and Rally generators produce Gleam/Erlang/JS source strings for SSR, hydration, browser boot, WebSocket transport, topics, and load/save dispatch.
Reading order
If you are new to the codebase, read these files in order:
src/rally.gleam: CLI entry point and pipeline orchestrationsrc/rally/internal/init.gleam: starter app scaffold generationsrc/rally/internal/generator/load_rpc.gleam: Rally Scoreboard Example load/save, SSR, browser, hydration, WebSocket, topic, and protocol generationsrc/rally/internal/format.gleam: formatting generated source
The generator files build Gleam/Erlang/JS source as strings. They are harder to read than normal code. Start with the Scoreboard example output, then read load_rpc.gleam with that output nearby.
Boundary with Libero
Rally and Libero split responsibility along a clear line:
Rally owns: pages, routing composition, SSR, WebSocket integration, browser lifecycle, hydration, topics, and runtime glue.
Libero owns: seed-driven type walking, wire identity, ETF and JSON typed codecs, decoder registration, atom registration, wire modules, and contract metadata.
Rally calls into Libero after it has extracted the page load/save/broadcast contracts. Rally owns request ids, result envelopes, WebSocket transport, server dispatch, hydration, SSR, and browser lifecycle glue. If you are working on how a typed payload becomes ETF or JSON data, you are working in Libero’s domain. If you are working on when a page sends, receives, routes, or handles that payload, you are working in Rally’s domain.
Project layout
src/
rally.gleam # CLI entry point
rally/internal/
init.gleam # Starter app scaffold generation
format.gleam # Runs gleam format on generated code
generator/
load_rpc.gleam # Rally Scoreboard Example generation
rally/runtime/
effect.gleam # navigation and broadcast effects
db.gleam # SQLite helpers
system.gleam # System DB, job queue
session.gleam # Session cookies
...
Testing
Tests live under test/rally/ for CLI, scaffold, generator, smoke, auth, and runtime contracts. Fixture apps live under fixtures/. Run with gleam test. Snapshot tests use Birdie.