Library / SDK
lfreist/hwinfo avatar
lfreist/hwinfo

hwinfo and the case for a modern C++ hardware inventory API

cross platform C++ library for hardware information (CPU, RAM, GPU, ...)

745 stars135 forksC++MIT

At a glance

What is it?
hwinfo is a cross-platform C++ library that answers what hardware a machine has and how it is being used, from CPU and RAM to disks, GPU, battery and network interfaces, with every query returning a std::expected so failures are values rather than exceptions. The trade-off is a hard C++23 floor and a deliberately opinionated API.
Who is it for?
hwinfo suits a C++ desktop or server application that needs to report hardware inventory and live utilization without shelling out to platform tools, and it suits a team that wants failures modelled as values rather than exceptions.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Every query returns std::expected, so errors are values

The API design decision that defines hwinfo is that no query throws. Each component is a plain aggregate returned by a free function, and the return type is result, which is spelled out in the example as std::expected, that is, a value or an error.

The example at the top of the project guide shows the shape of every call in the library:

cpp

#include <print>

int main() {
  auto cpus = hwinfo::cpus();  // hwinfo::result<std::vector<hwinfo::Cpu>>, i.e. std::expected<..., hwinfo::error>
  if (!cpus) {
    std::println(stderr, "{}", cpus.error());  // e.g. "cannot read /proc/cpuinfo: No such file or directory"
    return 1;
  }
  for (const auto& cpu : *cpus) {
    std::println("{} {}: {} cores, L3 {}", cpu.vendor, cpu.model, cpu.physical_cores,
                 cpu.cores.front().cache.l3.value_or(hwinfo::Bytes{}));
  }
  if (auto os = hwinfo::os()) {
    std::println("{}", *os);  // every type is formattable: "Ubuntu 24.04.1 LTS (x86_64, kernel 6.8.0-45-generic)"
  }
}

The error message in the comment is worth pausing on. It names the actual operating system file that could not be read, which means the error type carries a real diagnostic rather than a generic failure code, and a caller can print it directly to the user.

The consequence for callers is that the happy path and the failure path are equally visible in the source. There is no exception to catch and no error code to check, and the standard pattern is a boolean test on the result followed by dereferencing. Code that reads the API cold will find it hard to ignore the error case, which is the main argument for the expected style over throwing.

A fixed table of queries, each with its own header

The queries are enumerated in a table that pairs each function with what it returns and which header declares it, and the set is deliberately small.

hwinfo::computer() returns a Computer holding vendor, model, chassis and boot time. hwinfo::uptime() returns a std::chrono::seconds value that includes time asleep. hwinfo::cpus() returns one Cpu per socket, hwinfo::memory() returns total plus installed modules, hwinfo::gpus() and hwinfo::disks() return vectors, and hwinfo::os() returns an Os.

Two of them are less obvious. hwinfo::virtualization() returns a Virtualization describing whether the machine is a VM or a container, which is the kind of question a crash reporter or a telemetry agent wants to answer before deciding what to record. hwinfo::resource_limits() returns ResourceLimits with CPU quota, memory limit and affinity, which is the question you ask before you decide how many threads to spawn.

The remaining queries cover hwinfo::mainboard(), hwinfo::batteries() and hwinfo::network_interfaces(). The one-to-one mapping between function and header, hwinfo/cpu.h, hwinfo/ram.h, hwinfo/gpu.h and so on, means a build only needs to include what it uses, which matters for a library that is likely to sit inside a larger application.

What this table does not contain is a general escape hatch for arbitrary platform queries. The set of questions the library answers is the set of questions the author thought worth answering, and there is no documented way to ask a question that is not on the list.

Plain aggregates and ranges, not classes with behaviour

The library is explicit that values are regular types, copyable, comparable and formattable, and it says this makes them easy to use with ranges. The example shows what that looks like:

cpp
auto large_disks = hwinfo::disks().transform([](std::vector<hwinfo::Disk> disks) {
  return disks | std::views::filter([](const hwinfo::Disk& d) { return d.size > 1_TiB; })
               | std::ranges::to<std::vector>();
});

The composition here is the point. Because result is std::expected, it has transform, so the error case is handled by the type system and the success case continues as a value. Because Disk is an aggregate, a filter over a vector of them is a range operation rather than a loop with accessor calls. And the sizes carry their own unit, since the comparison is against 1_TiB using a user-defined literal from the hwinfo::literals namespace rather than a bare number of bytes.

A second example in the guide does the same thing for a CPU feature check:

cpp
bool avx2 = hwinfo::cpus().transform([](const auto& cpus) { return cpus.front().has_flag("avx2"); }).value_or(false);

Here a missing CPU list yields false rather than an exception, because value_or supplies the fallback. That is the whole error model in one line, and it explains why the author chose expected over the alternatives.

Every type is also formattable, which is what lets the library print an Os directly as a string.

Missing information is optional, and privileged reads show up there

Not every machine exposes everything, and the library models that with std::optional rather than with a sentinel value or a default. The guide states that information the platform does not expose, or that needs privileged reads, is a std::optional, and it names Disk::serial_number as an example.

This is a good design choice for a hardware library, because the alternatives are worse. A serial number of an empty string is ambiguous between a disk with no serial, a disk whose serial could not be read, and a platform that never had the concept. An optional distinguishes them, and it forces the caller to decide what to display when the value is missing.

The same reasoning applies to the CPU cache example in the opening snippet, which reads cpu.cores.front().cache.l3.value_or(hwinfo::Bytes{}), so a processor without an L3 cache formats as an empty byte count rather than as a crash. Requiring privileges is a separate axis: on many systems the serial number of a disk is readable only by root, and a library that quietly returned nothing there would look like a hardware fault.

For a telemetry or diagnostics tool, that distinction is the difference between a useful report and a misleading one.

C++23 is a hard floor, and the compiler list is explicit

The requirements section settles the standard question without ambiguity. hwinfo 2 requires C++23, naming std::expected, std::format and ranges as the reasons, and the tested compilers are listed as GCC 14 or newer, Clang 20 or newer with libstdc++ 14 or libc++ 20, Apple Clang 16 with Xcode 16 or newer, MSVC 19.40 with Visual Studio 2022 17.10 or newer, and MinGW-w64 with GCC 14 or newer.

Each of those floors has a reason behind it. GCC 14 and Clang 20 are the versions where std::expected and the library support around it matured. MSVC 19.40 corresponds to a specific Visual Studio 2022 update, which is the sort of detail that matters when a project is pinned to a particular agent image. Apple Clang 16 tracks Xcode 16, and that constraint is a real one for anyone building on macOS without a recent toolchain.

The build matrix in the CI badges mirrors the list, with separate workflows for Linux with clang, Linux with gcc, macOS, Windows with Visual Studio and Windows with MinGW, plus a clang format check. So all five combinations are exercised on every push, which is a stronger guarantee than a compiler list alone.

The cost of this strictness is real for adopters. A project on C++17 cannot use the library at all, and the release tags in the repository reflect that constraint, with a c++17 tag published on 2026-03-16 and a c++17 tag on 2026-10-10 alongside the main branch.

Monitoring and live utilization are part of the scope

The project description covers two jobs, and the second one is often missed. hwinfo provides an API for retrieving hardware information of components such as CPU, RAM, GPU, disks, mainboard, battery and network interfaces, and for monitoring their utilization.

The examples directory makes that concrete with two programs, examples/system_infoMain.cpp for the inventory side and examples/live_monitorMain.cpp for the monitoring side, alongside an examples/CMakeLists.txt. The library is therefore designed to be embedded in an application that reports what the machine is and separately one that watches how it is doing right now.

The repository layout supports that. There is an include/ directory for the public headers, src/ for the implementation, data/ for whatever per-platform or per-vendor data the parsers need, third_party/ for vendored dependencies, and .gitmodules for the submodules those dependencies come from. The root has a CMakeLists.txt, a cmake/ directory for the build logic, a .clang-format file and a code_style_check.sh script, so formatting is enforced mechanically.

The optional treatment of unavailable data is what makes monitoring practical. A utilization sample that cannot be read for one core in one polling interval is a missing optional in one sample, not a reason to abort the whole series.

The contribution rules are the clearest statement of the project's values

The project guide spends an unusual amount of space on how contributions should be produced, and it is the most distinctive thing about the repository.

The position is that hwinfo encourages the use of modern AI assisted development, but sets ground rules. AI must not replace your own reasoning about an issue, because blindly delegating a problem and accepting the proposed solution without understanding or critically evaluating it is likely to introduce incorrect assumptions and consequently poor code. The author is responsible for whatever they commit, which means understanding not only the code lines but the architecture and the implications of the commit to the project.

The stated aim follows: better code quality in general, because this is a free open source project and the point is not pushing features as fast as possible but developing and maintaining a stable and clean software architecture.

And the consequence is stated just as plainly. If a contribution shows the author has not adequately considered the problem, the proposed solution, or its implications, the author may reject it without further review. The closing paragraph clarifies that this is not an anti-AI position but a commitment to thoughtful engineering, sound architectural decisions and long-term maintainability, and that the maintainer does not have the time to compensate for contributions lacking those qualities regardless of how they were produced.

There is a warning at the top of the guide as well, noting that hwinfo.io is not affiliated with this repository and that any claim this is the official product repository of hwinfo.io is false. The project is MIT licensed, the default branch is main, and the last push to the repository was on 2026-10-15.

Editorial conclusion

hwinfo suits a C++ desktop or server application that needs to report hardware inventory and live utilization without shelling out to platform tools, and it suits a team that wants failures modelled as values rather than exceptions. It does not suit a codebase on C++17, since the library requires C++23 with std::expected, std::format and ranges, and it does not suit a project that needs a deep Windows registry or WMI query model, because the API surface is a fixed set of aggregate queries. Before adopting it, check your compiler against the tested list, GCC 14 or newer, Clang 20 or newer, Apple Clang 16 or newer, MSVC 19.40 or newer, or MinGW-w64 with GCC 14, and note that the last push was on 2026-10-15 with a C++17 release tag published on 2026-10-10.

Frequently asked questions

What does the hwinfo C++ library provide?

hwinfo provides a modern C++23 API for retrieving hardware information about CPU, RAM, GPU, disks, mainboard, battery and network interfaces, and for monitoring their utilization. Every component is queried through a free function such as hwinfo::cpus() or hwinfo::memory().

How does hwinfo report errors?

Each query returns hwinfo::result, which is std::expected, so a failure carries an error rather than throwing. The error can be printed directly, for example cannot read /proc/cpuinfo: No such file or directory, and information the platform does not expose is a std::optional.

Which compilers and standards does hwinfo 2 require?

It requires C++23, using std::expected, std::format and ranges. The tested compilers are GCC 14 or newer, Clang 20 or newer, Apple Clang 16 with Xcode 16 or newer, MSVC 19.40 with Visual Studio 2022 17.10 or newer, and MinGW-w64 with GCC 14 or newer.

Can hwinfo tell whether a machine is a virtual machine or container?

Yes. The query table lists hwinfo::virtualization() returning a Virtualization describing VM or container status, and hwinfo::resource_limits() returning CPU quota, memory limit and affinity, both declared in hwinfo/virtualization.h and hwinfo/resource_limits.h.

What are the requirements for contributing to hwinfo?

The project permits AI assisted development but requires that you reason about the issue yourself and that you understand the code, the architecture and the implications of your commit. The maintainer states that contributions lacking those qualities may be rejected without further review.

Official sources

  1. Issues
  2. lfreist/hwinfo on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/lfreist-hwinfo.svg)](https://hysenlabs.com/projects/lfreist-hwinfo)

Was this useful?