Terminal Rainbows in Zig: A Colorful cat-like Tool

Published on

Welcome back to Let’s Reinvent the Wheel. In this project, we explore how terminal text effects like rainbow coloring and simple animation work. We build a tiny silly Zig program that prints colorful text from stdin.

What You’ll Learn

This project is all about exploring how colorful terminal output works:

We implement all of this with Zig’s standard library, keeping the code small, clean, and educational.

Project Code

You’ll find the complete source code here: silly-cat

How It Works

Reading Input from Stdin

silly-cat reads from standard input line by line using Zig’s streamUntilDelimiter, capturing one line at a time into a buffer:

reader.streamUntilDelimiter(fbs.writer(), '\n', fbs.buffer.len)

This makes it compatible with piped input like:

echo "hello world" | silly-cat

Each line is processed independently, with a short delay between lines to support the animation effect.


Generating Rainbow Colors

For every character on the line, silly-cat calculates a rainbow color using a sine wave offset:

const red   = @sin(p / 10.0) * 127.0 + 128.0;
const green = @sin(p / 10.0 +/3) * 127.0 + 128.0;
const blue  = @sin(p / 10.0 +/3) * 127.0 + 128.0;

This produces a smooth hue transition across characters, giving it a “rainbow stream” appearance.

The position of the character and a global offset (which changes slightly between lines) are used to animate the color wave over time.


Writing Colored Output

Each character is wrapped with a 24 bit ANSI color escape sequence:

try writer.print("\x1b[38;2;{d};{d};{d}m{c}", .{ color.r, color.g, color.b, c });

At the end of each line, it resets the color with \x1b[0m.

The cursor is hidden at the start (\x1b[?25l) to reduce flicker during animation, and re-shown at the end (\x1b[?25h).


Animation Control

The animation is handled by a short sleep (std.time.sleep) between line renders, combined with a moving offset in the color calculation. This creates a subtle horizontal shimmer effect across multiple lines.

Tweak and Expand

External Resources