# What Is the openlogi-core Crate in OpenLogi? The Foundation Library Explained

> Discover the openlogi-core crate, OpenLogi's foundational library. Learn how its pure data structures and config logic enable WebAssembly and safe sharing across the ecosystem.

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

---

**The `openlogi-core` crate is the foundational library of the OpenLogi project that contains all pure data structures, device models, and configuration logic without any platform-specific dependencies, enabling WebAssembly compilation and type-safe sharing across the entire ecosystem.**

The OpenLogi project provides an open-source management layer for HID++ Logitech devices, utilizing a modular Rust architecture to separate concerns between data definitions and platform-specific I/O. The `openlogi-core` crate serves as the immutable base layer that defines what devices exist, what actions they can perform, and how user configurations are structured, ensuring that business logic remains portable and testable across all supported targets.

## Core Responsibilities and Data Models

The crate organizes its functionality into distinct modules, each responsible for a specific domain of the device management logic. This separation allows downstream components to import exactly the types they need without pulling in unrelated functionality.

### Device Model (src/device.rs)

The [`src/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/device.rs) file defines the pure representation of HID++ devices supported by the system. This module contains the `Device` struct and associated types that describe hardware capabilities, brand information, and device-specific metadata without any reference to actual hardware I/O operations. Because these definitions live in `openlogi-core`, the GUI, agent, and configuration tools all reference identical device structures.

### Action Catalog (src/action_ring.rs)

User interactions are organized into action rings, defined in [`src/action_ring.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/action_ring.rs). This module describes the circular menu of actions that can be bound to device buttons, including icon names, labels, and action types. The `ActionRing` type provides methods like `get(index)` to retrieve specific actions, ensuring the UI and configuration layers remain synchronized when displaying available options to users.

### Binding Definitions (src/binding/)

The `src/binding/` module hierarchy contains exhaustive definitions for input mappings, including key combinations, gestures, and swipe actions. These pure data structures describe *what* a binding should do without implementing *how* the system listens for those inputs. By centralizing binding definitions here, `openlogi-core` ensures that configuration files, validation logic, and runtime execution all agree on the structure of user-defined shortcuts.

### Configuration Format (src/config/)

User-editable TOML files are parsed using the types defined in `src/config/`. This includes the `Settings` struct and identity management logic that persists user preferences. The module provides platform-agnostic path resolution when the `fs` feature is enabled, allowing configurations to load from standard directories like `$HOME/.config/openlogi/config.toml`.

## Platform Independence and WebAssembly Support

A critical architectural constraint of `openlogi-core` is its complete isolation from side effects and platform-specific code. All host-specific functionality—such as HID++ I/O, filesystem access, and locale negotiation—lives in sibling crates like `openlogi-device`, `openlogi-hidpp`, and `openlogi-agent`.

This design enables **WebAssembly compilation**, verified by the CI job "wasm (portable crates)". Platform-specific capabilities are accessed only through feature-gated modules:

- **`fs` feature**: Enables [`src/paths.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/paths.rs) for filesystem path resolution and single-instance handling
- **`locale` feature**: Enables [`src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/locale.rs) for host-language negotiation

Because the core crate compiles without these features, it can target WebAssembly and other restricted environments where system calls are unavailable, while still providing the full data model for web-based configuration tools.

## Integration Pattern: Why Every Crate Depends on openlogi-core

The dependency graph of OpenLogi flows strictly upward: every other component imports `openlogi-core` to share a single source of truth. This guarantees **type safety** across the entire codebase when evolving the data model.

Consider how the agent and GUI initialize application state:

```rust
// Load the user configuration (requires the `fs` feature)
use openlogi_core::config::Settings;

fn load_user_config() -> anyhow::Result<Settings> {
    // `Settings::load` reads `$HOME/.config/openlogi/config.toml`
    Settings::load()
}

```

```rust
// Create an application instance that holds the runtime state.
// The `app` module contains the high-level entry point used by both GUI and agent.
use openlogi_core::app::App;
use openlogi_core::device::Device;

fn start_app(devices: Vec<Device>) -> App {
    // `App::new` builds the state from the list of discovered devices and the
    // user configuration.
    App::new(devices)
}

```

```rust
// Query the action ring for the icon to display in the UI.
use openlogi_core::action_ring::ActionRing;

fn get_icon_name(ring: &ActionRing, index: usize) -> Option<String> {
    ring.get(index).map(|action| action.icon_name().to_string())
}

```

These patterns demonstrate that **all business logic lives in `openlogi-core`** while surrounding crates handle I/O, platform integration, and user interaction.

## Key Source Files and Public API

The crate entry point at [`src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/lib.rs) controls public module re-exports, while internal organization follows strict domain boundaries:

| File | Purpose |
|------|---------|
| [`Cargo.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/Cargo.toml) | Declares dependencies and feature flags (`fs`, `locale`) |
| [`src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/lib.rs) | Public module re-exports; crate entry point |
| [`src/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/device.rs) | Pure representation of HID++ devices |
| [`src/action_ring.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/action_ring.rs) | Definition of the per-device actions ring |
| `src/binding/` | Binding types (key combos, gestures, swipe actions) |
| `src/config/` | TOML configuration schema and parsing logic |
| [`src/app.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/app.rs) | High-level application state used by GUI and agent |
| [`src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/locale.rs) | Host-language negotiation (feature-gated) |
| [`src/paths.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/paths.rs) | Filesystem paths for config/storage (feature-gated) |
| [`src/color.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/color.rs) | Shared color definitions |
| [`src/brand.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/brand.rs) | Brand information constants |
| [`src/diagnostics.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/diagnostics.rs) | Diagnostic and debugging utilities |

Together, these files constitute the **core data layer** that powers the entire OpenLogi ecosystem, from command-line configuration to graphical device management.

## Summary

- **`openlogi-core`** serves as the foundation crate containing all pure data structures and business logic for the OpenLogi project.

- It defines **device models**, **action catalogs** ([`src/action_ring.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/action_ring.rs)), **binding definitions** (`src/binding/`), and **configuration formats** (`src/config/`) without platform-specific dependencies.

- The crate compiles to **WebAssembly** and portable targets because it isolates side effects into feature-gated modules (`fs`, `locale`).

- Every other OpenLogi component imports this crate to ensure **type safety** and a single source of truth across the codebase.

- Key integration points include `Settings::load()` for configuration, `App::new()` for state initialization, and `ActionRing` for UI action definitions.

## Frequently Asked Questions

### Does openlogi-core handle HID++ communication directly?

No. According to the OpenLogi source code, `openlogi-core` intentionally contains no platform-specific code or hardware I/O. All HID++ communication, filesystem access, and locale negotiation live in sibling crates like `openlogi-hidpp` and `openlogi-device`, accessed only through feature-gated modules when enabled.

### Why can openlogi-core compile to WebAssembly?

The crate compiles to WebAssembly because it maintains a strict separation between pure data structures and side effects. By placing filesystem paths ([`src/paths.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/paths.rs)) and locale handling ([`src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/locale.rs)) behind optional feature flags (`fs` and `locale`), the core library compiles without system dependencies, enabling the CI job "wasm (portable crates)" to verify WebAssembly targets.

### How does openlogi-core ensure type safety across the OpenLogi project?

All components—from the GUI to the background agent—import their domain types exclusively from `openlogi-core`. This shared dependency means that changes to the `Device` struct in [`src/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/device.rs) or the binding types in `src/binding/` propagate compile-time verification to every consumer, preventing deserialization errors and logic mismatches between configuration and runtime.

### What are the main feature flags available in openlogi-core?

The crate exposes two primary feature flags: **`fs`**, which enables filesystem path resolution and configuration loading via [`src/paths.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/paths.rs), and **`locale`**, which enables host-language negotiation via [`src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/locale.rs). Both are disabled by default to maintain portability, allowing the crate to function in sandboxed environments like browsers or embedded systems.