# Core Components of the OpenLogi Architecture: A Modular Rust Breakdown

> Explore the core components of the OpenLogi architecture, a modular Rust system with a three-tier design across eleven specialized crates for GUI, agent, and orchestration logic.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: architecture
- Published: 2026-08-27

---

**OpenLogi uses a three-tier architecture separating the user-facing GUI, background agent process, and shared orchestration logic across eleven specialized crates.**

OpenLogi is an open-source input device manager written in Rust that provides advanced HID++ device control with a modular, cross-platform design. The architecture, documented in [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md), divides responsibilities between a pure IPC client GUI, a hardware-managing background agent, and a shared communication layer. Understanding these core components is essential for contributing to the AprilNEA/OpenLogi repository or extending its functionality.

## The Three-Tier System Design

The OpenLogi architecture enforces strict separation of concerns through three distinct tiers. This design prevents the GUI from blocking during hardware I/O while keeping device-critical code isolated in a persistent background process.

According to the source code in [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md), the tiers consist of:

- **GUI Tier**: Pure IPC clients that never touch hardware directly
- **Agent Tier**: The sole process with input hook access and HID++ device ownership
- **Orchestration Tier**: Shared types and contracts that coordinate DPI cycles, the Actions Ring session, and hook runtime

These tiers communicate through a **tarpc-based IPC contract** using bincode serialization, defined in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs).

## Core Components Breakdown

### GUI Layer: Desktop and Overlay

The GUI implementation splits user interaction between two crates. The **`openlogi-desktop`** crate (`crates/openlogi-desktop`) implements the main GPUI-based settings interface, while **`openlogi-overlay`** (`crates/openlogi-overlay`) renders the cursor-centered Actions Ring.

Both applications act as pure IPC clients with no direct hardware access. They connect to the agent via the IPC layer to fetch device state and trigger actions. The desktop entry point resides at [`crates/openlogi-desktop/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/main.rs), and the overlay launches from [`crates/openlogi-overlay/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-overlay/src/main.rs).

### Background Agent and Core Logic

The **`openlogi-agent`** crate ([`crates/openlogi-agent/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/main.rs)) runs as a background server that owns the input hook and performs all HID++ device I/O. This binary maintains session state and handles hardware communication exclusively.

The **`openlogi-agent-core`** crate contains the shared orchestration logic used by the agent, coordinating device discovery, input processing, and the Actions Ring session lifecycle. Keeping this logic in a separate crate allows both the real agent and mock implementations to share code.

### IPC Communication Layer

**`openlogi-ipc`** (`crates/openlogi-ipc`) implements the transport mechanism binding the architecture together. This crate uses **tarpc** for RPC definitions and **bincode** for serialization over local sockets, enabling type-safe communication between the GUI and Agent tiers.

The IPC definitions in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs) establish the contract that all GUI clients must follow when requesting device operations or state updates.

### Device Management Stack

Device interaction flows through three specialized crates:

- **`openlogi-hidpp`**: Low-level HID++ protocol handling
- **`openlogi-device`**: Higher-level device abstraction and state management ([`crates/openlogi-device/src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/lib.rs))
- **`openlogi-hid`**: Raw HID transport layer

These crates handle device enumeration, pairing workflows, and probe caching. They isolate the specifics of Logitech's HID++ protocol from the rest of the application, making the agent hardware-agnostic at the business logic layer.

### Input Hook and Injection

Platform-specific input handling lives in two dedicated crates:

- **`openlogi-hook`** ([`crates/openlogi-hook/src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hook/src/lib.rs)): Captures OS-specific input events before they reach applications
- **`openlogi-inject`** ([`crates/openlogi-inject/src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/lib.rs)): Synthesizes artificial input events back to the OS

The agent exclusively owns these capabilities, ensuring that input interception and injection happen only within the background process with appropriate system permissions.

### Core Types and Configuration

**`openlogi-core`** ([`crates/openlogi-core/src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/lib.rs)) provides pure data structures with zero I/O. This crate contains:

- TOML configuration parsing
- Device model definitions
- Action catalog schemas
- Locale negotiation logic

By keeping these types in a dedicated crate, both the GUI and Agent tiers can share data definitions without circular dependencies or I/O side effects.

### Supporting Infrastructure

Several utility crates complete the architecture:

- **`openlogi-assets`**: Manages device-render assets and cached fetches from OpenLogi mirrors
- **`openlogi-permissions`**: Reads privacy-permission status (macOS TCC, Linux device probes) and provides deep links to system settings
- **`openlogi-cli`** and **`openlogi`**: Thin command-line wrappers for headless operation
- **`xtask`**: Build-time tooling for packaging, bundling, and release manifest generation ([`xtask/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/xtask/src/main.rs))

## Running Individual Components

You can run each architectural component independently during development. This modular approach allows UI development without physical hardware present.

**Launch the full desktop GUI:**

```bash
cargo run -p openlogi-desktop

```

*Entry point:* [`crates/openlogi-desktop/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/main.rs)

**Start the background agent with real hardware access:**

```bash
cargo run -p openlogi-agent

```

*Entry point:* [`crates/openlogi-agent/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/main.rs)

**Run the overlay (Actions Ring) as a standalone IPC client:**

```bash
cargo run -p openlogi-overlay

```

*Entry point:* [`crates/openlogi-overlay/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-overlay/src/main.rs)

**Mock the agent for UI development without hardware:**

```bash
cargo run -p openlogi-agent --bin openlogi-agent-mock

```

*Mock binary:* [`crates/openlogi-agent/src/bin/mock_agent.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/bin/mock_agent.rs)

## Summary

- OpenLogi implements a strict three-tier architecture separating GUI clients, the hardware-managing agent, and shared orchestration logic.
- **Eleven specialized crates** handle distinct responsibilities ranging from HID++ protocol parsing (`openlogi-hidpp`) to permission management (`openlogi-permissions`).
- The IPC layer uses **tarpc and bincode** over local sockets to connect GUI applications with the background agent.
- **`openlogi-core`** provides pure data types shared across tiers without I/O dependencies.
- The agent exclusively owns input hooks and device access, while GUI crates remain pure IPC clients.

## Frequently Asked Questions

### What is the purpose of the OpenLogi Agent?

The Agent is a background server process that exclusively owns the input hook and performs all HID++ device I/O. It runs from [`crates/openlogi-agent/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/main.rs) and maintains session state, ensuring that hardware-critical code runs in a persistent process separate from the GUI.

### How do GUI applications communicate with hardware in OpenLogi?

GUI applications never communicate directly with hardware. Instead, they use the **`openlogi-ipc`** crate to send RPC calls via tarpc over local sockets to the Agent process. This IPC contract is defined in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs) and uses bincode for serialization.

### Can I develop the OpenLogi UI without having compatible hardware connected?

Yes. The repository provides a mock agent binary at [`crates/openlogi-agent/src/bin/mock_agent.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/bin/mock_agent.rs) that simulates device responses. Run it with `cargo run -p openlogi-agent --bin openlogi-agent-mock` to develop and test the GUI without physical Logitech devices present.

### Where is the low-level HID++ protocol handling implemented?

The HID++ protocol implementation resides in the **`openlogi-hidpp`** crate, with additional device abstraction in **`openlogi-device`** and raw HID transport in **`openlogi-hid`**. This stack handles device enumeration, pairing, and probe caching while isolating protocol specifics from the agent's business logic.