Choosing the Tech Stack
The choice of technology was a process of weighing comfort against control. I started with minimal experiments in C, primarily to familiarize myself with the Win32 API. The result was impressive: the binaries were tiny and consumed virtually no measurable system resources at runtime.
Evaluating Modern Alternatives
A brief foray into the world of Zig revealed its potential as a modern language, but it seemed unnecessary for this specific project, since the Windows API can already be addressed natively with remarkable simplicity in C.
Since StayAwake is a tray application, I also tested Go, drawing on prior experience in this area. However, as expected, Go’s convenience doesn’t justify its resource consumption:
- A Go runtime includes a garbage collector and scheduler, which inflates both the RAM footprint and binary size compared to C.
- For a tool intended to be “invisible,” this overhead was unacceptable.
The Final Stack: C + Zig
I therefore opted for the “hardcore” path: C for the logic, supported by Zig as a build tool. This combination proved ideal:
- C enables direct, unfiltered communication with the operating system.
- Zig serves as a powerful replacement for complex Makefiles or MSBuild. Without additional dependencies, it allows for the integration of app icons and the creation of highly optimized builds (LTO-optimized, stripped).
The result is a symbiosis of simplicity and maximum performance.
It’s fascinating to observe how the Zig toolchain elevates C projects. Instead of wrestling with resource-heavy Visual Studio or brittle Makefiles, using
zig buildprovides a modern interface to a classic problem. Rejecting Go here—despite its general appeal for such tools—demonstrates a consistent commitment to project goals: when ‘minimalism’ is the mandate, the C runtime (or rather, its absence) remains unbeatable.