A Rust portfolio application focused on architecture, realtime delivery, and runtime visibility.
eran_codes is the Rust workspace behind my portfolio site at https://eran.codes.
This project is a working portfolio site and a place to show how I structure Rust web systems with clear boundaries, realtime updates, and visible runtime behavior.
The focus is on system behavior rather than isolated features: crate boundaries, SSE-driven UI state, request tracing, and the operational surfaces around them.
- Boundary discipline.
http,app,domain, andinfraare separate crates with clear responsibilities. - Realtime delivery. UI state converges through SSE + Datastar with session-aware stream routing.
- Runtime visibility. Request metadata, backend flow, and live operational timelines are surfaced in the UI.
- Operational concerns in the app itself. Sessions are durable, tracing is layered, and the request-burst surface is there to inspect runtime behavior.
- Typed contracts across the stack. Maud components, domain newtypes and enums, and explicit workflow types keep rendering and business logic structured.
browser
-> axum router + handlers
-> app services
-> domain types and invariants
-> infra repositories + Postgres + Argon2
global SSE stream
-> session/tab keyed registry
-> Datastar patches for UI convergence
trace pipeline
-> live operational surface for the reader
-> deeper diagnostic stream for engineering visibility
At the crate-boundary level, the workspace stays intentionally layered:
browser
|
v
http
routing, handlers, SSE, Maud
|
v
app
use-case services
|
v
domain
types and invariants
infra supplies the Postgres, hashing, repository,
and session-backed runtime pieces used by the outer layers.
[src/main.rs](./src/main.rs) is the composition root. It wires:
- tracing
- Postgres-backed sessions
- app services
- the SSE registry
- the HTTP router
into one runtime.
These pages expose runtime behavior directly in the UI.
| Surface | Path | What to observe |
|---|---|---|
| Lab | /lab |
Live chat, request burst traffic, auth/session panels, and the operational timeline |
| Chat system | /work/chat-realtime |
Persisted messaging, moderation, rate limiting, and SSE fanout |
| Command + SSE | /work/command-sse |
Datastar command flow, server-authoritative state, and SSE convergence |
| Operational visibility | /work/operational-visibility |
Request tracing, backend flow grouping, and UI-visible runtime behavior |
| Auth durability | /register -> /login -> /protected |
Session lifecycle, auth enforcement, and secure persistent sessions |
While interacting, watch the operational timeline panel. It shows requests, commands, and state changes as they happen.
-
Visit
/lab. This is the quickest way to see the main pieces together: live chat, request burst traffic, auth/session panels, and the operational timeline. -
Visit the focused work pages.
-
Read the engineering rationale.
-
Inspect the crate boundaries.
Required environment:
HOSTPORTDATABASE_URLSESSION_SECRET(base64url, no padding, 64 bytes)
Optional environment:
SESSION_CLEANUP_INTERVAL_SECS(default3600)INFRA_DB_MAX_CONNECTIONS(default10)LOG_FORMAT(prettyorjson)
Start the app:
docker-compose up -d
cargo run --bin with_db -- sqlx migrate run --source crates/infra/migrations
cargo runThen open http://127.0.0.1:3000/ or http://127.0.0.1:3000/lab.
| Area | Role | Start here |
|---|---|---|
| domain | Pure business types and invariants | user and chat modules |
| app | Use cases, policy, and external contracts | auth and chat services |
| infra | Postgres, hashing, repositories, and migrations | auth repo, chat repo, config |
| http | Router, handlers, SSE, Maud views, component surfaces, and trace surfaces | router, handlers, views, trace_log |
| utils | Small shared helpers and developer tooling | visual_snapshot and support utilities |
-
Start at the docs hub
-
Why it is structured this way
-
How the runtime behaves
-
How the HTTP surface is organized
This repo favors:
- explicit boundaries over convenience coupling
- typed invariants over stringly state
- visible runtime behavior over hidden magic
- reusable render components over template duplication
- clear composition roots over implicit wiring
Those tradeoffs are consistent across the codebase.