System Health Tool is a Tauri 2 desktop app with a Rust backend and a React frontend. The frontend keeps the shell, layout, and presentation logic in TypeScript while the Rust backend owns the real system operations.
The important architectural rule is still the same:
src/lib/api.tsis the only frontend layer that talks to the backend.- Screen hooks call
api.ts. - Screen components render UI from hook state.
- Shared primitives keep the five screens visually and structurally consistent.
flowchart LR
subgraph Shell ["App shell"]
App["App.tsx"]
Nav["NavRail"]
Pages["Active screen"]
end
subgraph Frontend ["Frontend layers"]
Hooks["Screen hooks"]
UI["Shared UI primitives"]
Api["api.ts"]
Mock["mockApi.ts<br/>(browser preview only)"]
end
subgraph Backend ["Rust commands"]
Disk["disk.rs"]
Memory["memory.rs"]
Startup["startup.rs"]
Cleanup["cleanup.rs"]
Recommendations["recommendations.rs"]
end
App --> Nav
App --> Pages
Pages --> UI
Pages --> Hooks
Hooks --> Api
Api --> Mock
Api -- "invoke()" --> Disk
Api -- "invoke()" --> Memory
Api -- "invoke()" --> Startup
Api -- "invoke()" --> Cleanup
Api -- "invoke()" --> Recommendations
src/App.tsx is intentionally thin:
- owns the
Tabstate - renders the left nav rail on desktop widths
- renders a compact horizontal tab fallback on smaller widths
- switches the active screen with a small
framer-motiontransition
src/components/layout/NavRail.tsx is the only shell-level layout component today. It owns branding, navigation labels, and the desktop left rail.
src/components/ErrorBoundary.tsx wraps the entire app in main.tsx. If a React render crash occurs, it catches the error and displays a styled recovery screen with the error message and a reload button, instead of a blank white page.
The shared layer lives in src/components/ui/:
PageHeadergives every screen the same top command bar pattern.MetricCardstandardizes KPI presentation.SectionCardstandardizes section framing and headers.DataRowstandardizes dense review/list rows.StatusBadge,ProgressBar,AppCheckbox, andAppSwitchwrap the most repeated controls.Tooltipwraps Radix UI tooltips with the app's dark theme styling. Used for truncated paths and commands instead of nativetitleattributes.LoadingState,EmptyState, andStickyActionBarcover the common state and workflow patterns.
This is the main reason the screen files are shorter and more maintainable than the previous design.
Each major screen now owns its data flow in a dedicated hook:
useDashboardDatauseDiskCleanupuseMemoryDatauseStartupDatauseRecommendations
These hooks:
- fetch data
- compute derived metrics
- expose user actions
- expose an
errorfield so screens can render failure states - keep the React components mostly declarative
All five hooks follow the same pattern for error handling:
- Wrap the initial
boot()call in try/catch. - Wrap
refresh()in try/catch. - Store the error message in an
errorstate field. - Clear
erroron retry/refresh before re-fetching. - Return
errorso the screen component can decide how to render it.
Each screen renders errors differently depending on context:
- Loading + error: Shows an
EmptyStatewith the error message and a retry button. - Loaded + refresh error: Shows a warning banner above existing data (data becomes stale but still visible).
- Action error (e.g., toggle failure): Shows an inline error banner near the action.
The ErrorBoundary catches uncaught render errors at the top level.
src/lib/api.ts preserves the frontend contract and chooses the correct runtime path:
- In the real Tauri runtime, it calls Rust commands through
invoke(). - In browser-only dev mode, it uses
src/lib/mockApi.tsso the UI can be previewed and browser-tested without a native backend.
This fallback exists for frontend iteration only. The Rust backend remains the source of truth for real cleanup, memory, startup, and recommendation behavior.
The Recommendation.action_type field uses a typed union:
| Value | Behavior |
|---|---|
navigate_disk |
CTA navigates to the Disk Cleanup screen. |
navigate_memory |
CTA navigates to the Memory screen. |
navigate_startup |
CTA navigates to the Startup screen. |
info |
No navigation CTA; shows an "Info" badge instead. |
New action types must be added to the RecommendationAction union in src/lib/types.ts and handled in the getAction() switch in Recommendations.tsx.
The mock API (src/lib/mockApi.ts) covers most normal flows but has limitations:
- Cannot simulate backend errors (all mock calls succeed).
- Returns an empty recommendation list when the system is healthy, which exercises the empty state. But it cannot produce
action_type: "info"rows since the mock logic does not emit them. - Process kill always succeeds for non-system processes.
Use npm run tauri:dev to test real backend behavior.
Dashboard.tsx is an operational summary screen:
- health score is computed client-side from drive pressure, memory pressure, startup load, and cleanup opportunities
- quick clean still submits only
risk === "safe"items - drive capacity rows stay visible as a stable storage overview
- States: loading, error (banner above metrics), healthy (no alerts), quick-cleaning (button loading state)
DiskCleanup.tsx is a review workflow, not just a list:
- auto-scans on mount
- preselects safe items
- separates filtering from selection
- keeps grouped cleanup targets inside accordions
- submits
itemIdsanditemPathstogether tocleanItems() - States: scanning, scan error (retry surface), review, cleaning (dedicated progress screen), done (result log)
MemoryPanel.tsx is an inspector layout:
- summary metrics at the top
- process table in the primary column
- category mix, VM inventory, and problem-process sections in the secondary column
- kill actions remain disabled in the UI for system processes (shows "Protected" label)
- VM and problem process accordions auto-open when they contain actionable items
- States: loading, load error (retry surface), loaded, refresh error (stale-data banner)
StartupManager.tsx is a grouped operations list:
- entries grouped by impact
- recommendation badges stay visible
- toggles keep using opaque backend IDs so reversibility is preserved
- States: loading, load error (retry surface), empty (no entries), loaded, toggle error (inline banner)
Recommendations.tsx is an action queue:
- priority groups are rendered by severity
- CTA buttons map to tab navigation; info-only rows show an "Info" badge
- refresh stays manual because generating recommendations is relatively expensive
- States: loading, load error (retry surface), empty (healthy), loaded, refresh error (stale-data banner)
useDashboardDataloads drives, memory, startup items, and disk scan data.- The hook computes health score and summary alerts.
- Quick Clean filters to safe items only and refreshes the overview after cleanup.
useDiskCleanupscans on mount.- Safe items are preselected.
- The current filter changes visible groups only.
- Cleanup submits paired
itemIdsanditemPaths. - The completion screen renders the per-item result log from
CleanupSummary.
useMemoryDataloads RAM info, process list, and VM info in parallel.- The hook groups processes by category and derives zombie/process heuristics.
- Killing a process refreshes the memory snapshot.
useStartupDataloads startup entries.- Toggling an item calls
toggleStartupItem(id, enable). - The frontend updates local state optimistically after a successful response.
useRecommendationsloads the recommendation list once on mount.- Results are sorted into severity groups.
- CTA buttons switch tabs in the shell instead of duplicating remediation flows.
| Module | Commands | Notes |
|---|---|---|
disk.rs |
scan_disk, get_drive_info |
Enumerates cleanup targets and drive capacity. |
memory.rs |
get_memory_info, get_processes, kill_process, get_vm_info |
Handles RAM stats, process inventory, kill actions, and VM discovery. |
startup.rs |
get_startup_items, toggle_startup_item |
Reads from registry/startup folders and toggles launch-on-sign-in state. |
cleanup.rs |
clean_items |
Executes the actual cleanup and returns per-item results. |
recommendations.rs |
get_recommendations |
Generates prioritized actions from live system state. |
Current validation has two layers:
- Browser preview validation through
mockApi.tsfor layout, interaction, and automated UI checks. - Real Tauri validation through
npm run tauri:devfor any behavior that touches the actual system.
That split keeps frontend iteration fast without weakening the real command contract.