# llmfit TUI Interface: Interactive Terminal Architecture

> Explore the llmfit TUI interface a ratatui terminal app for AI model hardware compatibility. Discover keyboard driven interaction stateless rendering and real time filtering.

- Repository: [Alex Jones/llmfit](https://github.com/AlexsJones/llmfit)
- Tags: architecture
- Published: 2026-08-23

---

**The llmfit TUI interface is a ratatui-based terminal application that provides keyboard-driven interaction for exploring AI model hardware compatibility, featuring stateless rendering and real-time filtering capabilities.**

The llmfit TUI interface serves as the default interactive front-end for the AlexsJones/llmfit repository, replacing static command-line output with a dynamic terminal experience. When the binary starts without the `--cli` flag, control passes to the `llmfit-tui` crate, which orchestrates hardware detection, model fitting analysis, and user interaction through a strictly layered architecture.

## Architecture of the llmfit TUI

The interface follows a clean separation of concerns across four primary modules, enabling maintainable state management and rendering performance.

### Application State in tui_app.rs

The central state container resides in [`llmfit-tui/src/tui_app.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-tui/src/tui_app.rs), where the `App` struct holds the complete model-fit list, current filter configurations, selected row index, pagination state, and UI-specific settings. By centralizing all mutable state within this single structure, the application maintains predictable data flow and simplifies debugging across the event loop.

### Event Handling via crossterm

User input flows through [`llmfit-tui/src/tui_events.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-tui/src/tui_events.rs), which leverages **crossterm** to capture low-level keyboard events across platforms. This module translates raw key codes into high-level actions—such as navigation, sorting, filtering, or quitting—and applies these mutations to the `App` instance. The event loop runs continuously, polling for input while maintaining responsive 60-frame-per-second UI updates.

### Stateless Rendering with ratatui

The visual layer in [`llmfit-tui/src/tui_ui.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-tui/src/tui_ui.rs) implements **stateless rendering** using the **ratatui** crate. Drawing functions receive an immutable reference `&App` and render tables, detail panels, status bars, and filter widgets without modifying underlying data. This architectural choice ensures that rendering logic remains pure and side-effect free, allowing the same drawing code to execute safely across different application states.

### Theming Infrastructure

Visual consistency is managed through [`llmfit-tui/src/theme.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-tui/src/theme.rs), which defines centralized color palettes supporting both light and dark terminal modes. This module abstracts terminal color capabilities and provides consistent styling across all UI components, from table headers to popup dialogs.

## Data Flow from Hardware to Interface

The llmfit TUI interface processes information through a six-stage pipeline that keeps analysis logic separate from presentation:

1. **Hardware Detection**: `SystemSpecs::detect()` analyzes GPU, RAM, and CPU capabilities in the core library.
2. **Model Catalog Loading**: `ModelDatabase::new()` initializes the local cache of available AI models.
3. **Fit Analysis**: `build_model_fits()` computes compatibility scores between hardware constraints and model requirements.
4. **State Hydration**: The resulting vector of `ModelFit` objects populates the `App` state in [`tui_app.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_app.rs).
5. **Interaction Loop**: [`tui_events.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_events.rs) captures keyboard input and mutates state, while [`tui_ui.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_ui.rs) redraws the frame based on the updated reference.
6. **Plan Generation**: When users select a model, the UI displays execution details calculated by [`llmfit-core/src/plan.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-core/src/plan.rs), including memory estimates and runtime recommendations.

## Launching and Navigating the Interface

### Starting the TUI

Launch the terminal UI by executing the binary without CLI flags or with the explicit `--tui` flag:

```bash

# Default TUI mode

cargo run --release

# Explicit TUI invocation

cargo run -- --tui

```

The entry point in [`llmfit-tui/src/main.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-tui/src/main.rs) checks these flags, initializes the core `SystemSpecs` and `ModelDatabase`, creates the `App` instance with the computed model fits, and transfers control to the interactive event loop.

### Keyboard Navigation Controls

The interface supports vim-style navigation alongside standard arrow keys:

- **j** or **Down Arrow**: Move selection down the model list
- **k** or **Up Arrow**: Move selection up the model list
- **f**: Open the filter configuration panel
- **s**: Sort models by compatibility score
- **Enter**: Display detailed execution plan for the selected model
- **q** or **Ctrl+C**: Exit the application cleanly

These bindings are wired in [`tui_events.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_events.rs) and reflected in the status-bar help text rendered by [`tui_ui.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_ui.rs).

### Real-Time Filtering

Press **f** to access the filter dialog, where you can narrow results using structured syntax:

```text
provider: Ollama
quantization: Q4_K_M
run-mode: Gpu

```

The filter state persists in `App.filter_config` (defined in [`filter_config.rs`](https://github.com/AlexsJones/llmfit/blob/main/filter_config.rs)), with constraint logic applied through `apply_filters()` in [`tui_app.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_app.rs). This allows dynamic refinement of the model list without reloading the underlying hardware detection or model database.

## Decoupling from Core Logic

Despite its interactive complexity, the TUI remains fully decoupled from analysis logic. The `llmfit-core` crate handles all computation, including memory estimation in [`plan.rs`](https://github.com/AlexsJones/llmfit/blob/main/plan.rs) and hardware detection in [`system_specs.rs`](https://github.com/AlexsJones/llmfit/blob/main/system_specs.rs). This architecture allows the TUI to serve as one of multiple front-ends—alongside the classic CLI output in [`display.rs`](https://github.com/AlexsJones/llmfit/blob/main/display.rs) and HTTP API endpoints—while sharing identical underlying logic and ensuring consistent results across interfaces.

## Summary

- The llmfit TUI interface uses **ratatui** for terminal widget rendering and **crossterm** for input handling within the `llmfit-tui` crate.
- State management lives in [`tui_app.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_app.rs), events in [`tui_events.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_events.rs), and rendering in [`tui_ui.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_ui.rs) following a strict separation of concerns.
- The interface launches by default or via `--tui` flag, processing hardware detection through `SystemSpecs::detect()` before entering the interactive loop.
- Users navigate via vim keys (j/k) or arrow keys, filter results with **f**, and view detailed execution plans generated by [`llmfit-core/src/plan.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-core/src/plan.rs).
- Stateless rendering ensures consistent visual performance while maintaining complete decoupling from the core analysis engine.

## Frequently Asked Questions

### What Rust crates power the llmfit TUI interface?

The interface relies on **ratatui** for terminal widget rendering and **crossterm** for cross-platform keyboard and terminal I/O handling. These dependencies enable the interactive table views, popup dialogs, and responsive input processing that define the TUI experience.

### How does the TUI handle model filtering?

Filter state resides in `App.filter_config` within [`tui_app.rs`](https://github.com/AlexsJones/llmfit/blob/main/tui_app.rs). When users press **f** and enter criteria like `provider: Ollama`, the `apply_filters()` function processes these constraints against the loaded model list, updating the visible results without reloading the underlying hardware detection data.

### Can I use llmfit without the interactive TUI?

Yes. Passing the `--cli` flag bypasses the TUI entirely, routing output through [`llmfit-tui/src/display.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-tui/src/display.rs) for traditional command-line formatting. The core analysis functions in `llmfit-core` remain identical regardless of interface choice, ensuring consistent model-fit calculations.

### Where is the execution plan generated when I press Enter?

The detailed plan view draws data from [`llmfit-core/src/plan.rs`](https://github.com/AlexsJones/llmfit/blob/main/llmfit-core/src/plan.rs), which calculates memory requirements, suggested quantization levels, and optimal runtime configurations. The TUI renders this information in a dedicated detail panel while maintaining its stateless rendering architecture and read-only access to the underlying data.