This directory contains the React / TypeScript frontend for HardwareVisualizer.
The frontend talks to the Rust backend through Tauri commands generated by
tauri-specta.
src/
├── App.tsx # App shell, settings load, language/theme setup
├── main.tsx # React entry point
├── components/ # Reusable UI, charts, shared app components
│ ├── ui/ # Radix/Tailwind primitives
│ ├── charts/ # Recharts wrappers
│ └── shared/ # App-level shared components
├── features/ # Feature-owned UI, hooks, stores, and types
│ ├── hardware/ # Dashboard, usage graphs, insights
│ ├── settings/ # Settings screen and settings state
│ ├── menu/ # Sidebar navigation
│ ├── tray/ # Tray widget flyout UI
│ └── updater/ # App update UI
├── hooks/ # Cross-feature React hooks
├── lang/ # i18next translation JSON files
├── lib/ # Framework-agnostic helpers and Tauri wrappers
├── rspc/bindings.ts # Generated Tauri command bindings; do not edit
├── store/ # Cross-feature Jotai atoms
└── types/ # Shared frontend-only types
Keep feature-specific code under features/<feature>/ when the code is not
meaningfully reused elsewhere. Put reusable primitives in components/,
cross-feature hooks in hooks/, and pure helpers in lib/.
- Use generated commands from
src/rspc/bindings.ts. - Do not edit
src/rspc/bindings.tsby hand. - To expose a new backend command, add/register the Rust command in
src-tauri, runnpm run tauri:dev, then consume the regenerated binding. - Command results use the typed
Resultshape fromsrc/types/result.ts; check for errors before readingdata.
Backend error events are emitted as error_event. The frontend listener lives
in src/hooks/useTauriEventListener.ts and displays the error dialog.
Use the existing boundary when choosing where state lives:
- User-facing application preferences belong in
settings.json. Add typed Rust setter commands insrc-tauri/src/commands/settings.rs, persist through the Rust settings service, regenerate bindings, and updatefeatures/settings/hooks/useSettingsAtom.ts. - UI-local or transient state can use Tauri Store through
src/lib/tauriStore.tsandsrc/hooks/useTauriStore.ts. Examples include ephemeral selections, cached UI choices, or view state that can be reset without losing an explicit user configuration. - Cross-feature frontend state should use Jotai atoms under the owning feature
or
src/store/when it is genuinely shared.
Do not write user-facing preferences directly from the frontend with Tauri Store.
Translations use i18next and react-i18next.
Current language files live in src/lang/:
en.jsonja.jsonru.json
src/lib/i18n.ts imports these files and registers them as i18next resources.
src/types/i18next.d.ts keeps translation resources typed. The Settings
language selector derives its options from registered i18next resources, while
the Rust language service controls the default language fallback for first run.
New officially supported languages must be registered in both frontend i18next
resources and Rust SUPPORTED_LANGUAGES.
See docs/development/add-language.md
for the full checklist.
- Tailwind CSS is the styling layer.
- Reuse components from
src/components/ui/before adding new primitives. - Use feature-owned components for screen-specific UI.
- Use
react-i18nextfor display strings instead of hardcoded user-facing text. - Keep chart-specific wrappers in
src/components/charts/unless the chart is tightly owned by one feature.
Frontend tests are co-located with the code they cover:
- components:
Component.test.tsx - hooks:
useThing.test.ts - pure helpers:
helper.test.ts - feature workflows: under the owning
features/<feature>/tree
Use Vitest and Testing Library patterns already present in the repository. Prefer focused tests around behavior, command result handling, formatting, and state transitions.