A touch-optimized system monitoring dashboard for the HYTE Y70 Touch Infinite display (682x2560), built with Tauri v2, React 18, D3.js, and Tailwind CSS.
Vitrine replaces the Windows-only HYTE Nexus software with a native Linux application that provides real-time hardware telemetry, animated visualizations, and an optional AI advisor — all designed for the Y70's vertical touchscreen.
Vitrine is French for "glass display case" — a reference to the Y70's glass panel that showcases your hardware.
- Real-time telemetry — CPU, GPU, RAM, NVMe, network, fans via sysfs
- D3.js visualizations — Arc gauges, radial progress rings, sparklines, animated bars, history graphs
- Configurable pages — Multi-page carousel with swipe navigation
- Widget system — 7 built-in widgets, configurable layout via TOML
- AI System Advisor — Optional LM Studio integration for ambient hardware insights
- Dark/light theming — Accent color picker, glow effects, animation controls
- Settings drawer — Swipe down from top edge to configure everything
- Config hot-reload — Edit
config.tomland changes apply live
# System libraries
sudo dnf install webkit2gtk4.1-devel gtk3-devel libappindicator-gtk3-devel librsvg2-devel pango-devel
# Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Node.js + pnpm (if not already installed)
sudo dnf install nodejs
npm install -g pnpm
# Tauri CLI
cargo install tauri-cli --version "^2"git clone https://github.com/AppSprout-dev/vitrine.git
cd vitrine
pnpm install
pnpm tauri buildThe binary will be at src-tauri/target/release/vitrine.
chmod +x install.sh
./install.shThis will:
- Copy the binary to
~/.local/bin/vitrine - Create a default config at
~/.config/vitrine/config.toml - Install and enable a systemd user service (auto-starts on login)
- Auto-detect the Y70 display and configure KDE window rules (if applicable)
systemctl --user status vitrineTo restart after config changes:
systemctl --user restart vitrineConfig file location: ~/.config/vitrine/config.toml
[general]
polling_interval_ms = 1000 # Sensor polling rate (250-5000)
mock_sensors = false # Force mock data (for testing)
auto_start = true
target_display = "auto" # Auto-detect Y70, or specify output name
[theme]
mode = "dark" # "light" or "dark"
accent_color = "#60A5FA" # Any hex color
background_opacity = 0.85 # 0.5-1.0
enable_glow_effects = true
enable_animations = true
[temperature_thresholds]
cpu_warn = 75
cpu_critical = 90
gpu_warn = 80
gpu_critical = 95
[[pages]]
name = "System"
[[pages.widgets]]
widget_type = "cpu_monitor"
position = { col = 0, row = 0 }
size = { cols = 2, rows = 2 }
[[pages.widgets]]
widget_type = "gpu_monitor"
position = { col = 0, row = 2 }
size = { cols = 2, rows = 2 }
[[pages.widgets]]
widget_type = "ram_usage"
position = { col = 0, row = 4 }
size = { cols = 1, rows = 1 }
[[pages.widgets]]
widget_type = "nvme_storage"
position = { col = 1, row = 4 }
size = { cols = 1, rows = 1 }| Type | Description | Default Size |
|---|---|---|
cpu_monitor |
CPU temp, utilization, frequency, per-core bars | 2x2 |
gpu_monitor |
GPU temp, utilization, VRAM, power draw | 2x2 |
ram_usage |
System + swap memory radial gauges | 1x1 |
nvme_storage |
Drive temp, read/write throughput | 1x1 |
network_monitor |
Interface RX/TX speeds | 1x1 |
media_player |
MPRIS2 now-playing info | 2x2 |
system_advisor |
AI-powered hardware insights (requires LM Studio) | 2x1 |
The System Advisor widget connects to a locally-running LM Studio instance to provide ambient hardware insights. It periodically analyzes your telemetry and surfaces observations like thermal trends, efficiency tips, or anomaly alerts.
Vitrine works perfectly fine without it. The advisor is disabled by default if LM Studio isn't running.
- Install LM Studio and load a small model (we recommend
ibm/granite-4-h-tinyfor fast, clean responses — avoid "thinking" models like Qwen 3.5 which waste tokens on chain-of-thought) - Start the LM Studio local server (default:
http://localhost:1234) - Add to your
config.toml:
[advisor]
enabled = true
api_endpoint = "http://127.0.0.1:1234/v1/chat/completions"
model = "ibm/granite-4-h-tiny" # Or leave empty to auto-detect
interval_seconds = 90 # How often to generate insightsThe advisor will start generating insights after collecting 2 minutes of telemetry data. Tap an insight in the expanded view to get a more detailed explanation.
| Field | Default | Description |
|---|---|---|
enabled |
true |
Enable/disable the advisor |
api_endpoint |
http://127.0.0.1:1234/v1/chat/completions |
LM Studio API URL |
model |
"" (auto-detect) |
Model ID to use, or empty to pick first available |
interval_seconds |
90 |
Seconds between insight generation |
min_data_seconds |
120 |
Minimum telemetry data before first insight |
request_timeout_seconds |
180 |
HTTP timeout (increase for slow models) |
max_insight_history |
50 |
Max insights to keep in memory |
system_prompt |
(built-in) | Custom system prompt for the model |
- Rust 1.70+, Node.js 18+, pnpm
- Tauri CLI v2:
cargo install tauri-cli --version "^2"
pnpm install
pnpm tauri devThis starts Vite (frontend hot-reload) + Rust backend. On non-Linux systems, mock sensor data is used automatically.
Force mock sensors on Linux:
VITRINE_MOCK_SENSORS=1 pnpm tauri devpnpm lint # ESLint
npx tsc --noEmit # TypeScript type check
cd src-tauri && cargo clippy # Rust lintssrc-tauri/src/
├── lib.rs # App setup, polling loop, config watcher
├── commands.rs # IPC handlers (sensors, config, advisor)
├── config.rs # TOML config schema with serde
├── sensors/
│ ├── mod.rs # SensorProvider trait, SensorData structs
│ ├── cpu.rs # Linux sysfs reader
│ └── mock.rs # Mock data generator (auto on non-Linux)
└── advisor/
├── engine.rs # Advisor thread, scheduling, event detection
├── buffer.rs # Telemetry ring buffer with rolling stats
├── client.rs # HTTP client for LM Studio API
├── prompt.rs # Prompt construction, category classification
└── events.rs # Thermal/load/anomaly event detection
src/
├── App.tsx # Root: pages, theme, settings
├── hooks/
│ ├── useSensorData.ts # Tauri event subscription
│ ├── useConfig.ts # Config read/write via IPC
│ ├── useAdvisorInsights.ts # Advisor event + IPC
│ ├── useTheme.ts # DOM theme application
│ └── useHistoryBuffer.ts # Rolling data buffer
├── components/
│ ├── layout/ # PageCarousel, WidgetGrid, PageIndicator
│ ├── widgets/ # CpuMonitor, GpuMonitor, SystemAdvisor, etc.
│ ├── visualizations/ # ArcGauge, RadialProgress, Sparkline, etc.
│ └── settings/ # SettingsDrawer, GeneralTab, AppearanceTab
└── lib/
├── types.ts # TypeScript interfaces (snake_case)
├── constants.ts # Panel dimensions, colors
├── widgetRegistry.ts # Widget type -> component mapping
└── formatters.ts # Display value formatters
See CONTRIBUTING.md for setup instructions and guidelines.