stdio-zig
A teensy library that wraps stdin/stdout behind a clean, buffered API for Zig’s new std.Io interface (0.16+).
https://github.com/tacheraSasi/stdio-zig
In all my CLI projects I found myself writing the same three things over and over: allocate buffers, wire up stdout/stdin readers and writers, and remember to flush. This puts all of that in one Console struct declare two buffers, call init, and go.
Usage
const std = @import("std");
const stdio = @import("stdio");
pub fn main(init: std.process.Init) !void {
const io = init.io;
var write_buf: [4096]u8 = undefined;
var read_buf: [4096]u8 = undefined;
var console: stdio.Console = undefined;
console.init(io, &write_buf, &read_buf);
try console.printLine("What's your name?", .{});
const name = try console.readLine();
try console.printLine("Hello, {s}!", .{name});
}
The design is intentionally minimal: the entire library is one console.zig file with no dependencies beyond std. The struct holds both the concrete File.Writer/File.Reader (with their per-instance state) and an *Io.Writer/*Io.Reader interface pointer, giving callers the option to work through the abstract interface or access the underlying file handle if needed.
Recently I added a few quality-of-life methods prompt, confirm, readLineTrim, readLineOrNull that codify patterns I was tired of typing in every interactive script. readLineOrNull in particular makes EOF-handling loops much cleaner than catching error.EndOfStream at every call site.
One thing I learned while building this: Zig’s Io.Writer handles buffering internally via its buffer/end/vtable-drain pattern, so there’s no need for a separate buffered-writer abstraction. The library is essentially just wiring and naming conventions on top of that built-in machinery.
Supported Zig versions
0.16.x, 0.17.x-dev