How Fastfetch Identifies Installed Software Through Binary Detection

Fastfetch identifies installed software by locating executables in $PATH and extracting version strings directly from binary files using platform-specific parsers for ELF, PE, and Mach-O formats, falling back to executing --version only when necessary.

The fastfetch-cli/fastfetch repository implements a high-performance detection system that determines software versions without spawning subprocesses whenever possible. By parsing binary file formats directly, fastfetch minimizes system overhead while maintaining accurate version identification across Linux, Windows, and macOS platforms.

The Three-Step Binary Detection Pipeline

Fastfetch employs a standardized three-step pipeline to identify installed software versions. This architecture prioritizes static file analysis over dynamic execution to reduce latency and resource consumption.

Locate the Executable with ffFindExecutableInPath()

The detection process begins in src/common/impl/path.c where ffFindExecutableInPath() traverses the directories specified in $PATH. On Windows, the implementation utilizes SearchPathA for native compatibility, while Unix-like systems parse the colon-delimited PATH environment variable. This function returns the absolute filesystem path of the target binary, enabling subsequent direct file analysis without relying on shell execution.

Extract Version Strings Using ffBinaryExtractStrings()

The core detection logic resides in src/common/binary.h and its platform-specific implementations. The ffBinaryExtractStrings() function maps the binary into memory and scans the read-only data section—.rodata on ELF systems, .rdata on Windows PE files, and the appropriate segment in Mach-O binaries.

The platform-specific implementations handle their respective file formats:

The function accepts a callback parameter that examines each string literal. When the callback identifies a matching version pattern, it stores the result and returns false to terminate the scan immediately, optimizing performance by avoiding unnecessary iteration through the remaining binary content.

Fallback to --version Execution

When binary string extraction fails to locate a version identifier, modules fall back to executing the binary with standard version flags. The ffProcessAppendStdOut() function captures output from commands like --version, then applies post-processing to isolate the version number. This hybrid approach ensures compatibility with software that embeds version data only in runtime output or dynamic libraries.

Platform-Specific Implementation Details

Fastfetch's binary detection abstracts file format complexity through unified interfaces while maintaining platform-native parsing capabilities.

ELF Binary Parsing on Linux and Unix

The Linux implementation in src/common/impl/binary_linux.c leverages libelf to access the .rodata section of ELF executables. This section contains string literals compiled into the binary, including version banners and build identifiers. The parser iterates through this section sequentially, passing each candidate string to the module-specific callback function for pattern recognition.

PE Binary Parsing on Windows

For Windows executables, src/common/impl/binary_windows.c handles Portable Executable (PE) format parsing. The implementation maps the file into memory and specifically targets the .rdata section, where Microsoft compilers store read-only initialized data. This approach captures version strings embedded during the build process without requiring process execution or command-line parsing.

Mach-O Handling for macOS

Apple platforms require special handling due to universal binaries containing multiple architectures. The src/common/impl/binary_apple.c implementation parses Mach-O headers to locate the appropriate segment for string extraction, ensuring accurate version detection across both Intel and Apple Silicon systems without architecture-specific execution.

Practical Implementation: Detecting Neovim

The editor detection module in src/detection/editor/editor.c demonstrates the callback-based extraction pattern. When identifying Neovim installations, fastfetch uses the following approach:

/* editor.c – part of the editor detection module */
static bool extractNvimVersionFromBinary(const char *str,
                                         FF_MAYBE_UNUSED uint32_t len,
                                         void *userdata)
{
    if (!ffStrStartsWith(str, "NVIM v")) return true;
    ffStrbufSetS((FFstrbuf *)userdata, str + strlen("NVIM v"));
    return false;            /* stop scanning */
}

/* After locating the binary path … */
ffBinaryExtractStrings(result->path.chars,
                       extractNvimVersionFromBinary,
                       &result->version,
                       (uint32_t)strlen("NVIM v0.0.0"));

The callback checks for the "NVIM v" prefix, extracts the trailing version string into the result buffer, and returns false to halt further scanning. The minimum length parameter (uint32_t)strlen("NVIM v0.0.0") filters out shorter strings that cannot contain valid version data, reducing unnecessary callback invocations.

Extending Detection to New Software

Adding support for additional tools requires implementing three components:

  1. String recognition callback – A function matching the tool's specific version marker (e.g., "v0.0.0" patterns or branded prefixes)
  2. Minimum length parameter – Passed to ffBinaryExtractStrings() to skip obviously short strings
  3. Fallback handling – Optional execution of --version flags when binary extraction returns empty results

The window manager detection in src/detection/wm/wm_linux.c illustrates this pattern when identifying Hyprland:

/* wm_linux.c – detecting Hyprland */
ffBinaryExtractStrings(buffer.chars,
                       extractHyprlandVersion,
                       result,
                       (uint32_t)strlen("v0.0.0"));
if (result->length == 0) {
    /* fallback */
    ffProcessAppendStdOut(result,
        (char *const[]){ buffer.chars, "--version", NULL });
}

This modular architecture allows contributors to add new software detection by implementing only the recognition logic, while the heavy lifting of file parsing and memory management remains handled by the common binary extraction framework.

Summary

Fastfetch's binary detection system provides efficient software identification through direct file analysis:

  • Path resolution via ffFindExecutableInPath() locates binaries in $PATH without environment assumptions
  • Format abstraction through ffBinaryExtractStrings() handles ELF, PE, and Mach-O transparently
  • Callback architecture enables early termination upon version discovery, minimizing I/O operations
  • Execution fallback ensures compatibility when static strings are unavailable
  • Minimal overhead avoids process spawning until necessary, reducing detection latency across all supported platforms

Frequently Asked Questions

How does fastfetch identify installed software without running the programs?

Fastfetch identifies installed software by parsing executable binary files directly rather than executing them. The tool uses ffBinaryExtractStrings() to scan read-only data sections (.rodata in ELF, .rdata in PE) where compilers store version strings, extracting this information through file I/O operations that avoid process creation overhead and shell execution.

What file formats does fastfetch support for binary version detection?

Fastfetch supports three major executable formats: ELF (Linux and BSD systems), PE (Windows executables), and Mach-O (macOS). Each format has a dedicated implementation—binary_linux.c, binary_windows.c, and binary_apple.c—that understands the specific section layouts and string storage mechanisms of its respective platform.

Why does fastfetch fall back to executing --version commands?

Fastfetch falls back to --version execution when ffBinaryExtractStrings() fails to locate recognizable version patterns in the binary's read-only sections. Some applications generate version strings dynamically at runtime or store them in resources that require execution to access. The fallback ensures comprehensive coverage while maintaining performance by attempting static extraction first.

How can I add detection for a new tool to fastfetch?

To add detection for new software, implement a callback function that recognizes the tool's specific version string pattern (such as "ToolName v1.0.0"), then call ffBinaryExtractStrings() with this callback and an appropriate minimum string length. If binary extraction fails, implement a fallback using ffProcessAppendStdOut() to execute the binary with --version. Reference existing implementations in src/detection/editor/editor.c or src/detection/wm/wm_linux.c for structural patterns.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →