# Fastfetch Hardware Detection Architecture: Modular Design and OS Abstraction

> Explore fastfetch's modular hardware detection architecture. Discover how OS abstraction enables portable CPU, GPU, memory, and disk info across Linux, Windows, and macOS.

- Repository: [fastfetch-cli/fastfetch](https://github.com/fastfetch-cli/fastfetch)
- Tags: architecture
- Published: 2026-03-30

---

**TLDR:** Fastfetch implements a layered hardware detection system where OS-specific implementations are abstracted behind uniform public APIs, allowing portable detection of CPU, GPU, memory, and disk information across Linux, Windows, and macOS.

According to the fastfetch-cli/fastfetch source code, the hardware detection system is organized under `src/detection/` using a three-tier architecture: OS-specific collectors, platform-agnostic dispatchers, and high-level result consumers. This design separates data acquisition from presentation, enabling consistent hardware reporting across all supported platforms.

## Core Architecture Principles

The architecture follows three fundamental principles that govern all detection modules from CPU to physical disk enumeration.

### Separate Result Types

Every hardware component defines a dedicated result struct that holds collected data. For example, [`src/detection/cpu/cpu.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu.h) defines `FFCPUResult` containing fields for `name`, `vendor`, `frequencyMax`, and `temperature`. Similarly, [`src/detection/gpu/gpu.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu.h) declares `FFGPUResult` with vendor information, device names, and memory specifications. These structs act as the strict contract between detection logic and consuming modules, ensuring type safety across the codebase.

### Per-OS Implementations

Detection logic resides in files following the pattern `<component>_<os>.c`. At compile time, the build system selects the appropriate implementation for the target platform. For CPU detection, the repository contains [`src/detection/cpu/cpu_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu_linux.c) (procfs/sysfs parsing), [`src/detection/cpu/cpu_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu_windows.c) (registry/WMI queries), and `src/detection/cpu/cpu_apple.m` (sysctl/IOKit). Each file implements a private `ffDetect<Component>Impl` function that populates the result struct using native system APIs.

### Uniform Public API

Every detection module exposes a single entry point: `ffDetect<Thing>(const FF<Thing>Options*, FF<Thing>Result*)`. This function returns `const char*` containing an error message or `NULL` on success. The dispatcher lives in the platform-agnostic source file (e.g., [`src/detection/cpu/cpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu.c)), which forwards calls to the OS-specific implementation and performs generic post-processing such as stripping vendor prefixes or normalizing frequency units.

## Detection Flow and Data Pipeline

The hardware detection process follows a strict five-stage pipeline:

1. **Module Entry Point** – A Fastfetch module (e.g., [`src/modules/cpu/cpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/modules/cpu/cpu.c)) initializes an empty result struct and invokes the public API.
2. **Dispatcher** – The platform-agnostic file ([`src/detection/cpu/cpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu.c)) receives the call and forwards it to `ffDetectCPUImpl`.
3. **OS-Specific Collection** – The implementation file gathers raw data using native APIs such as procfs on Linux, Windows registry queries, or macOS IOKit.
4. **Post-Processing** – The dispatcher performs generic cleanup, such as normalizing CPU vendor strings or converting memory units.
5. **Result Consumption** – The calling module formats the populated struct for terminal output or JSON serialization.

```

+----------------------+          +------------------------+
| src/modules/cpu.c    |  --->    | src/detection/cpu.c   |
+----------------------+          +------------------------+
                                           |
                +--------------------------+--------------------------+
                |                         |                         |
   +---------------------+   +---------------------+   +---------------------+
   | cpu_linux.c         |   | cpu_windows.c       |   | cpu_apple.m         |
   +---------------------+   +---------------------+   +---------------------+

```

## Multi-Backend Detection Strategies

Some components support multiple detection backends to handle varying hardware configurations. The `ffDetectGPU` function in [`src/detection/gpu/gpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu.c) implements a fallback chain: **PCI → Vulkan → OpenCL → OpenGL**.

The detection function receives an options struct containing a `detectionMethod` enum. When `FF_GPU_DETECTION_METHOD_AUTO` is specified, Fastfetch attempts methods in order of preference, falling back to the next if a method fails or is disabled at compile time. This logic is contained entirely within the component's main detection file, while OS-specific files in [`src/detection/gpu/gpu_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu_linux.c) and [`src/detection/gpu/gpu_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu_windows.c) handle the low-level API interactions for each respective method.

## Extending the Architecture

Adding new hardware support requires four steps without modifying existing display logic:

- **Define the contract** – Create [`src/detection/foobar/foobar.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/foobar/foobar.h) with the `FFFooBarResult` struct and `ffDetectFooBar` function declaration.
- **Implement OS collectors** – Add [`foobar_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar_linux.c), [`foobar_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar_windows.c), and [`foobar_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar_apple.c) implementing the private `ffDetectFooBarImpl` function.
- **Add dispatcher** – Create [`foobar.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar.c) with the public `ffDetectFooBar` function that routes calls to OS implementations and performs data cleaning.
- **Create module** – Add [`src/modules/foobar/foobar.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/modules/foobar/foobar.c) to call the detection API and handle output formatting.

The existing `ffPrint` and `ffGenerateJsonResult` patterns automatically integrate the new module into JSON generation and CLI output without additional glue code.

## Implementation Examples

### Detecting CPU Information

The following example demonstrates how to call the CPU detection API from a standalone program:

```c
#include "detection/cpu/cpu.h"

int main(void) {
    FFCPUResult cpu = {
        .temperature = FF_CPU_TEMP_UNSET,
        .frequencyMax = 0,
        .frequencyBase = 0,
        .name = ffStrbufCreate(),
        .vendor = ffStrbufCreate(),
    };

    const char *err = ffDetectCPU(&(FFCPUOptions){}, &cpu);
    if (err) {
        fprintf(stderr, "CPU detection failed: %s\n", err);
        return 1;
    }

    printf("CPU: %s (%s) @ %u MHz\n",
           cpu.name.chars,
           cpu.vendor.chars,
           cpu.frequencyMax ? cpu.frequencyMax : cpu.frequencyBase);

    ffStrbufDestroy(&cpu.name);
    ffStrbufDestroy(&cpu.vendor);
    return 0;
}

```

### Configuring GPU Detection Methods

To explicitly control the GPU detection backend, populate the options struct before calling `ffDetectGPU`:

```c
#include "detection/gpu/gpu.h"

int main(void) {
    FFlist gpus;
    ffListInit(&gpus);
    
    FFGPUOptions opt = {
        .detectionMethod = FF_GPU_DETECTION_METHOD_AUTO,
        .temp = true,
    };

    const char *err = ffDetectGPU(&opt, &gpus);
    if (err) {
        puts(err);
        return 1;
    }

    for (uint32_t i = 0; i < gpus.length; ++i) {
        FFGPUResult *gpu = (FFGPUResult*)ffListGet(&gpus, i);
        printf("%s: %s %s\n", gpu->vendor.chars, gpu->name.chars, gpu->memoryType.chars);
    }
    
    ffListDestroy(&gpus);
    return 0;
}

```

## Summary

- Fastfetch organizes hardware detection into **separate result structs**, **per-OS implementations**, and **uniform public APIs** located under `src/detection/`.
- The architecture follows a **five-stage pipeline**: module entry → dispatcher → OS-specific collection → post-processing → result consumption.
- **Multi-backend components** like GPU detection use fallback chains (PCI → Vulkan → OpenCL → OpenGL) controlled by the `detectionMethod` option in [`src/detection/gpu/gpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu.c).
- **Extensibility** requires only adding new files in `src/detection/` and `src/modules/` without modifying core logic, thanks to the generic `ffPrint` and `ffGenerateJsonResult` patterns.
- All OS-specific code is isolated in files like [`cpu_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/cpu_linux.c), [`gpu_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/gpu_windows.c), and [`memory_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/memory_apple.c), enabling clean cross-platform support through compile-time selection.

## Frequently Asked Questions

### How does fastfetch handle cross-platform compatibility?

Fastfetch achieves cross-platform compatibility by isolating OS-specific code into separate implementation files (e.g., [`cpu_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/cpu_linux.c), [`cpu_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/cpu_windows.c), `cpu_apple.m`). A platform-agnostic dispatcher in the main component file (e.g., [`src/detection/cpu/cpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu.c)) forwards calls to the appropriate OS-specific `ffDetect<Component>Impl` function at compile time. This ensures that Linux procfs queries, Windows registry access, and macOS IOKit calls never mix in the same compilation unit, preventing platform-specific code from leaking into the generic logic.

### What is the fallback order for GPU detection in fastfetch?

According to the [`src/detection/gpu/gpu.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu.c) implementation, fastfetch attempts GPU detection in the following order: **PCI** (direct hardware enumeration) → **Vulkan** (graphics API) → **OpenCL** (compute API) → **OpenGL** (legacy graphics API). The `FF_GPU_DETECTION_METHOD_AUTO` enum value triggers this chain automatically, skipping any methods disabled at compile time or unsupported by the hardware. Users can force a specific method by setting the `detectionMethod` field in the options struct passed to `ffDetectGPU`.

### How can I add support for a new hardware component to fastfetch?

To add a new detector, create a header file in `src/detection/foobar/` defining `FFFooBarResult` and `ffDetectFooBar`, then implement `ffDetectFooBarImpl` in OS-specific files ([`foobar_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar_linux.c), [`foobar_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar_windows.c), etc.). Add a dispatcher in [`foobar.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/foobar.c) to route calls and clean data, and finally create a module in `src/modules/foobar/` to format the output. The existing architecture automatically integrates the new component into JSON generation and CLI output without additional glue code, as all modules follow the standardized `ffDetect<Thing>` pattern.

### Where are the OS-specific detection implementations located?

OS-specific implementations follow the naming convention `src/detection/<component>/<component>_<os>.c`. For example, Linux CPU detection resides in [`src/detection/cpu/cpu_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/cpu/cpu_linux.c), Windows GPU detection in [`src/detection/gpu/gpu_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/gpu/gpu_windows.c), and macOS memory detection in [`src/detection/memory/memory_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/memory/memory_apple.c). These files contain the low-level system calls using native APIs like procfs, sysctl, or Windows Management Instrumentation (WMI), while the corresponding `src/detection/<component>/<component>.c` files handle the generic dispatching logic.