Tuicr Architecture: A Deep Dive into the Modular Rust Code Review Tool
Tuicr employs a modular, crate-style architecture that separates VCS abstraction, review modeling, persistence, and UI rendering into distinct layers, enabling extensible terminal-based code reviews across Git, Mercurial, and Jujutsu repositories.
Tuicr is a Rust-based terminal UI (TUI) application designed for interactive code review. Its architecture follows clean separation of concerns, organizing functionality into discrete modules that handle everything from configuration parsing to remote forge integration. Understanding the Tuicr architecture reveals how the tool maintains flexibility across different version control systems while providing both interactive and programmatic interfaces.
High-Level Architectural Overview
The Tuicr architecture follows a layered design pattern that isolates core logic from external dependencies. At the highest level, the application divides responsibilities into four primary layers: the core application state, adapter layers for VCS and forge integration, persistence mechanisms, and the user interface stack.
This separation allows individual components—such as the Git backend or the ratatui-based renderer—to evolve independently without affecting the central review logic. The architecture supports multiple version control systems through trait-based abstraction, enabling users to review code from Git, Mercurial, or Jujutsu repositories using identical workflows.
Core Components
Entry Point and Application Bootstrap (src/main.rs)
The application lifecycle begins in src/main.rs, which serves as the primary entry point. This module parses CLI arguments using the clap crate, loads user configuration from disk, and resolves the UI theme based on environment variables and config files.
During initialization, the entry point probes for keyboard enhancement capabilities and creates a TerminalFeatures session. It then instantiates the main App struct and enters the event loop, dispatching raw terminal events to the appropriate handlers. The entry point also triggers update checks in the background, ensuring users receive notifications when new releases are available on crates.io or GitHub.
Central State Management (src/app.rs)
The App struct in src/app.rs encapsulates the entire application state. This central state machine holds:
- A boxed VCS backend (
Box<dyn VcsBackend>) for repository operations - The current
ReviewSessioncontaining all review data - UI panel states (file list, diff view, comment navigator, commit selector)
- Input mode state determining which handlers process keystrokes
- Runtime options controlling diff view behavior and commit selection
The App struct acts as the single source of truth, with all state mutations flowing through its methods. This centralization simplifies debugging and ensures consistency across the TUI's various panels and modes.
Version Control Abstraction (src/vcs/)
Tuicr implements a trait-based abstraction layer in src/vcs/traits.rs that decouples the review logic from specific version control implementations. The VcsBackend trait defines common operations including:
info()– retrieves repository metadataget_working_tree_diff()– generates diff data for reviewfetch_context_lines()– extracts surrounding code context for comments
Concrete implementations reside in submodules supporting Git (via libgit2 with CLI fallback for sparse checkouts), Mercurial, and Jujutsu. This architecture allows Tuicr to treat all VCS systems uniformly, enabling features like cross-VCS review sessions and consistent diff rendering regardless of the underlying tool.
Review Domain Model (src/model/)
The data structures defining a code review reside in src/model/review.rs. These types represent the core domain concepts:
ReviewSession– the root container for a review, including metadata and file reviewsFileReview– per-file review state and associated commentsComment– individual review comments with positioning dataCommentTypeandLineSide– enums categorizing comment severity and diff positioning
These structures serialize to JSON for disk persistence and enable the non-interactive CLI subcommands. The model is deliberately VCS-agnostic, focusing purely on the review domain rather than repository specifics.
Persistence Layer (src/persistence/storage.rs)
Review sessions persist to disk via src/persistence/storage.rs, which manages the ~/.local/share/tuicr/reviews/ directory. The persistence layer implements atomic writes using temporary files and rename operations, preventing data corruption during crashes.
To handle concurrent access, the system employs lock files when multiple processes attempt to modify the same review session. This architecture ensures that users can safely run Tuicr in multiple terminals or integrate it into CI pipelines without risking session corruption.
Remote Forge Integration (src/forge/)
The src/forge/traits.rs module defines the ForgeBackend trait, abstracting interactions with remote hosting platforms. Concrete implementations support:
- GitHub via the
ghCLI tool - GitLab via the
glabCLI tool
These backends fetch pull request details, retrieve remote diff data, synchronize review threads, and publish completed reviews. By delegating to the official CLI tools rather than direct API integration, Tuicr inherits authentication handling and platform-specific behaviors automatically.
Terminal User Interface (src/ui/)
Built on ratatui (formerly tui-rs) and crossterm, the UI layer in src/ui/app_layout.rs manages the terminal interface. The layout divides the screen into distinct panels:
- File list sidebar showing changed files
- Main diff view with syntax highlighting
- Comment navigator for thread management
- Commit selector for multi-commit reviews
The ui::render function executes each tick, drawing the current state to the terminal buffer. This declarative approach separates presentation logic from state management, with the App struct providing the data and the UI layer handling visual representation.
Event Handling and Command Dispatch (src/handler/)
Input processing occurs in src/handler/mod.rs, which implements a command pattern for user interactions. The architecture converts terminal events into Action enums via map_key_to_action, then routes these actions through dispatch_action based on the current InputMode.
Individual handler functions (handle_*) mutate the App state in response to specific actions like scrolling, toggling comment visibility, or entering edit modes. This dispatch architecture centralizes input logic while allowing mode-specific behaviors, such as different keybindings in the diff view versus the comment editor.
Non-Interactive CLI Facade (src/review_cli.rs)
Beyond the TUI, Tuicr exposes a programmatic interface through src/review_cli.rs. This module provides the tuicr review subcommands (list, add, export) that operate directly on the ReviewStore library facade.
This architectural layer enables scripting and CI integration, allowing automated systems to create, modify, and export reviews without launching the interactive interface. The CLI facade uses the same persistence and model layers as the TUI, ensuring consistency between interactive and batch workflows.
Self-Update Mechanism (src/update/check.rs)
The update subsystem in src/update/check.rs periodically queries crates.io and GitHub releases for newer versions. When updates are available, the system downloads and verifies release assets, then safely replaces the running binary. This self-modifying capability requires careful handling of file permissions and process replacement on Unix and Windows systems.
Practical Usage Examples
Initializing the Tuicr application programmatically follows this pattern:
let config = tuicr::config::load_config().unwrap_or_default();
let theme = tuicr::theme::resolve_theme_with_config(
None,
None,
config.theme.as_deref(),
config.theme_dark.as_deref(),
config.theme_light.as_deref(),
config.appearance.as_deref(),
)?;
let mut app = tuicr::app::App::new(
theme,
config.comment_types,
false,
tuicr::app::AppStartupOptions { /* … */ },
)?;
Adding comments via the library facade allows integration with external tools:
use tuicr::{AddCommentRequest, CommentTarget, ReviewStore};
let store = ReviewStore::new()?;
let session = store.get_review("my-repo", "my-session")?;
let req = AddCommentRequest {
target: CommentTarget::Line { file: "src/main.rs".into(), line: 42 },
comment_type: tuicr::model::CommentType::Issue,
body: "Explain the purpose of this block".into(),
..Default::default()
};
store.add_comment(&session, req)?;
store.save_review(&session)?;
For CI pipelines and scripting, the non-interactive interface exports review data as JSON:
tuicr review list --repo owner/repo --all --json
Summary
- Tuicr architecture separates concerns into distinct modules: entry point, core state, VCS abstraction, domain models, persistence, forge integration, UI rendering, and event handling.
- The
VcsBackendtrait insrc/vcs/traits.rsenables support for Git, Mercurial, and Jujutsu through a unified interface. - State management centers on the
Appstruct insrc/app.rs, which coordinates theReviewSession, UI panels, and input modes. - Persistence uses atomic writes and lock files in
~/.local/share/tuicr/reviews/to prevent data corruption. - Remote forge integration abstracts GitHub and GitLab through the
ForgeBackendtrait, delegating to official CLI tools. - The UI stack combines
ratatuifor rendering with a handler-based event system for input processing. - A separate CLI facade in
src/review_cli.rsenables non-interactive usage for automation and CI/CD workflows.
Frequently Asked Questions
What VCS backends does Tuicr support?
Tuicr supports Git, Mercurial, and Jujutsu through a trait-based abstraction layer defined in src/vcs/traits.rs. The default Git implementation uses libgit2 for performance but falls back to the Git CLI when handling sparse checkouts or other edge cases. All backends implement the VcsBackend trait, exposing methods like get_working_tree_diff() and fetch_context_lines() that work uniformly across repository types.
How does Tuicr handle concurrent access to review sessions?
The persistence layer in src/persistence/storage.rs implements file-based locking and atomic write operations. When saving a review session, Tuicr writes to a temporary file first, then performs an atomic rename operation to replace the existing session file. Lock files prevent race conditions when multiple Tuicr instances attempt to modify the same review simultaneously, ensuring data integrity across terminal sessions.
Can Tuicr be used without the interactive TUI?
Yes, Tuicr provides a non-interactive CLI through src/review_cli.rs that exposes the ReviewStore library facade. Users can list, create, and modify reviews using commands like tuicr review list --json or tuicr review add without launching the terminal interface. This architecture enables CI/CD integration and scripting workflows while using the same underlying persistence and model layers as the interactive mode.
What UI framework does Tuicr use for terminal rendering?
Tuicr builds its interface on ratatui (a maintained fork of tui-rs) combined with crossterm for cross-platform terminal control. The UI architecture in src/ui/app_layout.rs uses a panel-based layout system where ui::render draws the complete interface each frame based on the current App state. Input handling is decoupled from rendering through the handler modules in src/handler/, which map terminal events to state mutations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →