Module Map Reference

File-by-file codebase map with feature gates and target architecture boundaries.

πŸ”—Reference β€” module map

Hand-written 2026-07-27. ~8,100 lines of Rust in src/.

Two orthogonal gating axes: cargo features (cli, server, python; all opt-in, default = []) and target arch (wasm32 vs not).

πŸ”—Crate roots

filegatewhat
src/lib.rsβ€”18 lines of module declarations; crate docs are include_str!("../README.md")
src/main.rsclithe exp binary: init_tracing() then run_cli()
src/app/main.rswasm32the expman-app binary: mount_to_body(App)
build.rsβ€”invokes trunk build --release when server is on. Read docs/how-to/build-and-run.md before touching.
// src/lib.rs
pub mod core;                                             // always
#[cfg(all(feature = "server", not(wasm32)))] pub mod api;
#[cfg(wasm32)]                               pub mod app;
#[cfg(feature = "cli")]                      pub mod cli;
#[cfg(feature = "python")]                   pub mod wrappers;

πŸ”—src/core/ β€” always compiled

filegatewhat
models.rsβ€”ExperimentConfig, MetricValue, VectorRow, RunStatus, RunMetadata, ExperimentMetadata, ProjectMetadata β€” the storage models
dto.rsβ€”the wire types: Experiment, Project, ProjectDetail, Run, Artifact, GlobalStats, ServerConfig, ReadmeContent, InteractiveBackend, … Compiled for native and wasm32 so the server and the frontend share one definition; src/app/models.rs only re-exports them
error.rsβ€”ExpmanError (Arrow/Parquet variants are non-wasm only)
engine.rsnot wasm32LoggingEngine, LogLevel, LogCommand, background_task
storage.rsnot wasm32Parquet read/write, YAML helpers, list_runs/list_experiments/list_artifacts, ArtifactInfo, the project helpers (set_experiment_project, list_project_experiments), and the shared run index (RunEntry, RunQuery, query_runs, parse_tag_expr, is_run_stale, looks_alive)
projects.rsnot wasm32one-way project sync from a YAML manifest: ProjectManifest, sync_project, README rendering, the generated marker
sweep.rsnot wasm32sweep expansion (grid/random, seeded SplitMix64), trial command/env rendering, sbatch emission
sysmetrics.rsnot wasm32subprocess probes for GPU/CPU/RAM: ProbeSpec, SystemSampler, the nvidia-CSV and generic-JSON parsers
provenance.rsnot wasm32git/command/hostname/scheduler capture written to provenance.yaml

The wasm boundary is here: models and error are the only core modules the frontend sees. It reuses the data types but gets no engine, no storage, and no Arrow/Parquet/tokio.

Re-exported at core:: root: LoggingEngine, LogLevel, ExpmanError, ExperimentConfig, MetricValue, RunMetadata, RunStatus, VectorRow. Not re-exported (reach via the module path): models::ExperimentMetadata, storage::ArtifactInfo, error::Result, all storage free functions.

core/mod.rs:21-23 also has a doc-only pub mod jupyter_integration {} that exists purely to inline src/app/README.md into rustdoc.

πŸ”—src/api/ β€” server feature, non-wasm

filewhat
mod.rsrouter, CORS, serve(), graceful shutdown
state.rsAppState (base_dir, jupyter, tensorboard, shutdown token), ServerConfig β€” flag-shaped, no file config; parses jupyter_command into a JupyterCommand when building the manager
projects.rs Β· experiments.rs Β· runs.rs Β· metrics.rs Β· artifacts.rs Β· stats.rshandlers β€” see http-api
frontend.rsrust-embed of dist/, SPA fallback
jupyter_service.rs1331 lines: JupyterCommand (the configured launch command line), NotebookTemplateConfig (flag β†’ convention β†’ built-in) + NotebookContext (placeholder values), .ipynb rendering with JSON-escaped substitution, the metadata.expman staleness stamp, backend detection, port scan 8888–9999, spawn/status/stop. 23 unit tests from :890.
jupyter_handlers.rsper-run and __multi__ handlers; builds the NotebookContext, reading {{project}} from the experiment's experiment.yaml
tensorboard_service.rsuntracked. 175 lines, near-verbatim clone of the Jupyter manager. Port scan 6006–7999. No tests.
tensorboard_handlers.rsuntracked. 5 handlers.

πŸ”—src/app/ β€” wasm32 only (Leptos 0.8 CSR)

filewhat
mod.rsApp, sidebar shell, routes
main.rswasm entry
models.rsthin re-export of core::dto (since 2026-07-28). Previously hand-mirrored JSON types, which drifted; add fields to core::dto instead
fetch.rs411 lines of gloo_net calls returning Result<T, String>
utils.rsSidebarContext, CHART_COLORS, Liang–Barsky clipping, canvasβ†’PNG download
pages/dashboard.rs/ β€” global stats + recent experiments + recent projects
pages/projects.rs/projects β€” project grid and creation modal
components/hparams.rsthe Compare tab: params Γ— final-metrics table plus an SVG scatter, fed by /projects/{p}/runs
pages/project_detail.rs/projects/:id β€” overview with markdown README and experiments list
pages/experiments.rs/experiments
pages/experiment_detail.rs/experiments/:id β€” tabs + run-selection sidebar + metadata editing
pages/settings.rs/settings β€” one debug_enabled toggle in localStorage
pages/not_found.rsfallback
components/charts.rs~1013 lines: MetricsView, LineChart, ScalarChart. Hand-rolled pan/zoom over plotters-canvas.
components/runs_table.rstable + CSV/LaTeX/Typst export via blob download
components/artifacts.rsartifact browser, tabular preview
components/console.rslive log via raw web_sys::EventSource
components/interactive.rsJupyter tab β€” iframes http://localhost:{port}
components/tensorboard.rsuntracked. TensorBoard tab, single-run only.
components/zoom.rsshared zoom controls

Frontend styling is Tailwind from a CDN hardcoded in src/app/index.html:8. stylist is a declared dependency that is used nowhere.

πŸ”—src/cli/ β€” cli feature

Single mod.rs: clap definitions plus every subcommand implementation. See cli.

πŸ”—src/wrappers/ β€” python feature

mod.rs re-gates pub mod python; python/mod.rs (298 lines) is the #[pymodule]. See python-api.

πŸ”—Outside src/

pathwhat
wrappers/python/the PyPI package: expman/{__init__,cli,tensorboard}.py, pyproject.toml, tests/
tests/integration_test.rs (12 core tests), api_test.rs (7 HTTP tests), cli_test.rs (10 binary tests)
examples/rust/logging.rs, test_rust.rs
examples/python/basic_training.py, singleton_usage.py, tensorboard_migration.py
Justfileevery build/test/lint/release command
flake.nixdevShell + packages.expman + packages.python3Packages.expman-rs
.github/workflows/11 workflows β€” see release
dist/trunk output, gitignored but shipped in the crate via include

πŸ”—Stale in-tree docs

src/api/README.md, src/app/README.md, and src/app/components/README.md are rendered into rustdoc via #![doc = include_str!]. src/api/README.md is stale β€” it documents a nonexistent /api/events endpoint and mentions utoipa. Prefer docs/reference/.