High-Level Overview
NightFlow is a Tauri v2 desktop application. The frontend is built with Preact + Signals for a lightweight, reactive UI. The backend is Rust, providing native performance, memory safety, and access to system APIs.
Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| UI Framework | Preact + Signals | Lightweight reactive rendering (3KB core) |
| Terminal | xterm.js + WebGL addon | Hardware-accelerated pseudo-terminal |
| Styling | Vanilla CSS | Custom design system, no framework overhead |
| Bundler | Vite 7.x | Fast HMR and optimized production builds |
| Desktop Runtime | Tauri v2 | Native window, IPC, system APIs, auto-update |
| Backend | Rust (Edition 2024) | Memory-safe, high-performance core |
| PTY | portable-pty | Cross-platform pseudo-terminal for local/SSH |
| Async Runtime | Tokio | Non-blocking I/O, SSH connections |
| Storage | IndexedDB | Client-side persistent storage (idb) |
| Model Viewer | Netron | Embedded neural network architecture viewer |
| External Links | tauri-plugin-opener | Opens URLs in system default browser |
Frontend Architecture
The frontend is a single-page application built with Preact. Routing is handled client-side with a simple signal-based router.
Key Modules
Views
Dashboard, Experiments, Run Detail, Compare Runs, Dataset Browser, Interpretation, Netron, Terminal, Settings
Components
Reusable UI: Sidebar (with Buy Me a Coffee link), Header, Charts (Line/Bar), RunsTable, Confusion Matrix, Training Panel, System Metrics, Tutorial Overlay
State
Preact Signals for reactive state. Each domain (projects, experiments, training, dashboard, queue, router, theme) has its own signal store.
Database
IndexedDB via idb. All data (projects, runs, metrics, settings) persists locally with zero server dependency.
Why Preact?
- 3KB core — a fraction of React's bundle size
- Signals — fine-grained reactivity without re-rendering entire component trees
- React compatibility — can use React ecosystem libraries via preact/compat
- Fast startup — critical for a native desktop app
Backend Architecture
The Rust backend is organized into focused modules, each handling a specific domain. It communicates with the frontend via Tauri's IPC system (commands and events).
Modules
| Module | Responsibility |
|---|---|
main.rs | Tauri app bootstrap, plugin registration, shared state |
pty.rs | Spawning and managing pseudo-terminals for local shell and SSH |
ssh.rs | Async SSH connections via Tokio for remote training workflows |
fs.rs | Reading datasets, dataset browsing with automatic split detection, managing checkpoints, handling model exports |
training.rs | Launching Python training scripts, streaming output |
interpretation.rs | Triggering model interpretation (GradCAM, etc.) and returning results |
runs.rs | Parsing and managing experiment run data |
system.rs | CPU, memory, and GPU utilization monitoring; Hugging Face Hub model push |
env.rs | Environment detection and Python/conda setup |
Why Rust?
- Memory safety — no segfaults, no data races, guaranteed at compile time
- Performance — native speed, no garbage collector pauses
- Tiny binary — NightFlow ships as a single binary (~15MB vs 100MB+ for Electron)
- Tokio — first-class async runtime for non-blocking I/O
IPC Layer
Communication between frontend and backend uses Tauri's command system:
- Commands — frontend invokes Rust functions (e.g.,
invoke('start_training', { config })) - Events — backend emits typed events the frontend subscribes to (e.g., training progress, PTY output)
- Streaming — real-time data (metrics, terminal output) is pushed via event listeners
Tauri v2 generates TypeScript bindings from Rust command signatures, ensuring type-safe IPC across the stack.
Project Structure
NightFlow/ ├── src/ # Frontend source │ ├── views/ # Page-level views (Dashboard, Charts, Settings, etc.) │ ├── components/ # Reusable UI (Sidebar, Header, RunsTable, TrainingPanel, etc.) │ ├── state/ # Preact Signal stores (projects, experiments, training, queue, etc.) │ ├── db/ # IndexedDB (idb) persistence layer │ ├── hooks/ # Custom Preact hooks (useTerminal) │ ├── utils/ # Shared utilities (configBuilder, exportRuns, notifications) │ ├── app.jsx # App shell + router │ ├── main.jsx # Entry point │ └── style.css # Global styles ├── src-tauri/ # Rust backend │ ├── src/ │ │ ├── main.rs # Tauri app bootstrap, plugin registration │ │ ├── pty.rs # PTY management │ │ ├── ssh.rs # SSH connections │ │ ├── fs.rs # File system operations │ │ ├── training.rs # Training orchestration │ │ ├── interpretation.rs # Model interpretation │ │ ├── runs.rs # Run data parsing │ │ ├── system.rs # System metrics │ │ └── env.rs # Environment detection │ ├── capabilities/ # Tauri permission definitions │ ├── Cargo.toml # Rust dependencies │ └── tauri.conf.json # Tauri configuration ├── public/ # Static assets (Netron, icons) ├── docs/ # Documentation site (this!) ├── index.html # Vite entry HTML └── vite.config.js # Vite configuration
Build & Release
NightFlow uses GitHub Actions for CI/CD:
- Frontend build — Vite compiles and bundles the Preact app
- Backend build — Cargo compiles the Rust binary with
--releaseoptimizations - Packaging — Tauri bundles everything into platform-specific installers
- Release — Artifacts are uploaded to GitHub Releases automatically
| Platform | Format | Typical Size |
|---|---|---|
| macOS | .dmg |
~15 MB |
| Windows | .exe (NSIS) |
~12 MB |
| Linux | .deb / .AppImage |
~14 MB |