DocsStart here
How Rahti works
A build step reads your directories and writes ordinary Rust. The server renders the first response. The browser mounts what the server named. Nothing is discovered at runtime.
From a saved file to a served response
Rahti renders the initial response on the server. PulsePoint compiles and binds reactive expressions in the browser after the document loads. Between the two sits a build step that turns conventions into code.
src/app + src/components + src/models + src/migrations
|
v
rahti-build scans conventions
|
+--> src/routes.rs (generated, checked in)
+--> src/components/mod.rs (generated, checked in)
+--> src/models/mod.rs (generated, when a db is configured)
+--> src/migrations/mod.rs (generated, carries the Migrator)
+--> .rahti/manifest.json (generated tooling metadata)
+--> public/css/styles.css (built/copied according to config)
|
v
Rust handlers render Html
|
v
browser loads /js/main.js
|
v
PulsePoint v2 mounts reactive blocksWhich means main.rs has no magic in it. It builds the generated router, binds a listener, and serves — you can read the whole server in one screen:
// src/main.rs — the whole server, and nothing hidden from you.
pub use rahti;
mod components;
mod routes;
#[tokio::main]
async fn main() {
let app = routes::router();
let listener = rahti::listen(routes::HOST, routes::PORT).await;
println!("Server running on http://{}", listener.local_addr().unwrap());
axum::serve(listener, app)
.with_graceful_shutdown(async {
rahti::shutdown_signal().await;
})
.await
.unwrap();
}The workspace
| Crate | Role |
|---|---|
| rahti | The server runtime: Html, layouts, errors, RPC, streaming, uploads, auth, and — behind the ws feature — sockets. |
| rahti-macros | html!, #[component], #[rpc], #[socket]. Re-exported by rahti. |
| rahti-build | The build step: scans conventions, generates the router and modules, compiles CSS. |
| cargo-rahti | cargo rahti new and cargo rahti upgrade. |
| rahti-ui | An example installable component library. |
What the runtime exports
Html,Render,RenderJsandJson;- layout and error-boundary response layers, including the one that names the document a response was rendered in;
Error,ErrorInfoandResult;- RPC parsing, serialization, CSRF, streaming and upload types;
auth: a signed session cookie, a route-protection policy, and the guard layer that applies it — no user storage, no password handling, no providers, no roles;- link-time component RPC registration, and socket registration when the
wsfeature is on; listen: in dev a busy port falls forward to the next free one; in release it is an error;- development reload routes and graceful-shutdown coordination.
What the macros do
html!parses typed inline HTML, separates Rust from client expressions, escapes interpolated data, and stamps component boundaries.#[component]validates a PascalCase function, stamps its returned root, and generates the hidden named-props companion the tag form calls through.#[rpc]preserves the Rust function and generates its request shim and registry entry.#[rpc(auth)]adds a session check ahead of reading the payload.#[socket]generates the shim that reads the connection's first frame into the parameters.#[socket(auth)]refuses the handshake with a 401 before the upgrade.
What the build step does
On every relevant Cargo build, rahti-build:
- reads
rahti.config.json; - scans the route convention files and
src/components/*.rs; - validates route, RPC and socket-name conflicts;
- detects component-library dependencies through Cargo metadata;
- generates routes, modules and the manifest;
- generates model and migration wiring when a database is configured — without depending on SeaORM or reading any of its code;
- compiles or copies CSS, including component-library styles;
- emits Cargo watch directives for every relevant path.
Generated artifacts
All of these are checked in on purpose: a clone builds and runs without a code generator having to succeed first, and a generated diff is reviewable.
src/routes.rs the Axum router, checked in
src/components/mod.rs module declarations for every component file
src/models/mod.rs entity modules, when a database is configured
src/migrations/mod.rs migration modules and the Migrator, in filename order
.rahti/manifest.json routes, layouts, components, rpcs, sockets, db
public/css/styles.css compiled or copied, and deliberately committedWhen behaviour is unclear
The framework keeps an explicit source-of-truth order:
- executable tests;
- the implementation in
crates/; - generated output —
src/routes.rs,.rahti/manifest.json; - the examples under
src/app/andsrc/components/; - the convention documents — which is what this site is.
Generated output is evidence, not an editing surface.
The browser runtime asset
PulsePoint ships as a prebuilt bundle. Nothing in the workspace compiles or bundles JavaScript, and a checkout is complete as it stands. public/js/main.js imports the minified runtime, installs twMerge, and calls pp.mount() once the DOM is ready.
