SolidJS Frontend Design
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Keynobi's frontend is built using SolidJS, a declarative JavaScript library for building user interfaces that utilizes fine-grained reactivity. The frontend operates within a WKWebView as part of a Tauri 2.0 application architecture, serving as a companion tool for Android development. Its primary purpose is to provide a high-performance, reactive interface for build log streaming, logcat monitoring, device management, and MCP (Model Context Protocol) server interaction.
The design prioritizes performance through the use of SolidJS Stores for state management and specialized components like virtualized lists to handle large log buffers (up to 50,000 entries) without compromising UI responsiveness.
Sources: AGENTS.md:3-10, README.md:1-5
Architecture and Core Technologies
The frontend architecture follows a decoupled pattern where UI components react to changes in centralized stores, which in turn communicate with a Rust backend via Tauri's IPC (Inter-Process Communication).
Tech Stack Overview
| Layer | Technology |
|---|---|
| Framework | SolidJS + TypeScript |
| Build Tool | Vite |
| State Management | SolidJS Stores (createStore, produce) |
| IPC Types | ts-rs (Auto-generated Rust → TS bindings) |
| Styling | CSS Variables + Inline Styles (for dynamic reactivity) |
Sources: AGENTS.md:3-15, package.json:45-55
Component Hierarchy and Layout
The application layout is structured into a persistent shell containing a custom title bar, sidebars for project and device management, a main content area with tabbed navigation, and a status bar for real-time metrics.
The App.tsx file serves as the orchestration layer, registering global keybindings and actions via a centralized registry.
Sources: src/App.tsx:280-340, README.md:120-150
State Management and Reactivity
Keynobi uses SolidJS's fine-grained reactivity system to manage complex application states. State is primarily housed in domain-specific stores located in src/stores/.
Store Pattern
Stores are defined using createStore, allowing for deeply nested reactive objects. The produce function is utilized for immutable-style updates within a mutable API.
- build.store.ts: Manages build phases (
idle,running,success,failed), task details, and structured error/warning lists. - ui.store.ts: Tracks active tabs, sidebar collapse states, and panel visibility.
- mcp.store.ts: Tracks the status of the Model Context Protocol server and client connections.
Sources: src/stores/build.store.ts:25-50, AGENTS.md:13, README.md:100-115
Performance Optimization: Batching and Throttling
To prevent UI "flooding" from high-frequency backend events (like adb logcat or Gradle build logs), the frontend implements batching logic. For example, build log lines are collected in a buffer and flushed to the store every 50ms.
Key UI Systems
The Log Viewing System
The LogViewer is a shared component used for displaying both Gradle build logs and Android Logcat. It leverages VirtualList to ensure that only visible rows are rendered in the DOM, which is critical for the 50,000-entry ring buffer maintained by the backend.
Features of the LogViewer:
- Filtering: Supports level-based filtering (ERR, WARN, INFO, DBG, TRC) and source filtering.
- Auto-scroll: Implements "smart" auto-scroll that pauses when the user manually scrolls up.
- Reactivity: Uses
createMemoto derive filtered views efficiently.
Sources: src/components/common/LogViewer.tsx:160-230, CHANGELOG.md:45-55
Command Palette and Action Registry
Keynobi implements an AI-friendly "Action Registry" where every keyboard shortcut is mapped to a named action. This allows the same logic to be triggered via:
- Physical keyboard shortcuts (e.g.,
Cmd+R). - The Command Palette (
Cmd+Shift+P). - The MCP server (allowing AI agents to trigger UI actions).
Sources: src/App.tsx:48-80, AGENTS.md:20-25
Status Bar and Monitoring
The StatusBar provides real-time feedback on the application's environment and internal health. It integrates several specialized indicators:
- Health Center: Summarizes system checks (Java, SDK, ADB).
- Memory Monitor: Displays the current memory footprint of the frontend.
- Log Monitor: Shows the size of the disk-based log folder and triggers rotation visualizers.
Sources: src/components/layout/StatusBar.tsx:320-370, src/components/health/HealthPanel.tsx:640-680
Development and Build Configuration
The frontend development environment is managed by Vite. The configuration includes specific optimizations for the Tauri environment and Sentry telemetry.
- Vite Configuration: Defines aliases (e.g.,
@/forsrc/) and handles environment variable injection for versioning and Sentry DSNs. - Type Generation: Uses
ts-rsto ensure that TypeScript types exactly match Rust structs defined in the backend. - Security: The
tauri.conf.jsondefines a strict Content Security Policy (CSP) to allow Sentry ingestion while blocking unauthorized external connections.
Sources: vite.config.ts:35-65, src-tauri/tauri.conf.json:20-30, AGENTS.md:65-70
Summary
The Keynobi frontend design leverages SolidJS to create a high-performance developer tool that feels native to macOS. By combining fine-grained reactivity with efficient data handling strategies—such as virtualized lists, log batching, and an action-based registry—the frontend maintains a fluid user experience even under heavy loads from streaming Android system logs and build outputs. Significant architectural emphasis is placed on the bridge between Rust and TypeScript to maintain type safety and performance across the IPC boundary.