Apply visual shaders — colour, animation, character substitution — to text in your terminal
  • Go 94.5%
  • Just 5.5%
Find a file
ryan 550c15e5f3 chore: switch from dependabot to renovate
Renovate offers richer grouping, scheduling, and supply-chain
controls than Dependabot. New configuration:

- Weekly schedule (early Mondays)
- Group all gomod updates into a single PR (deps: prefix)
- Group all GitHub Actions updates into a single PR (ci: prefix)
- Auto-merge minor/patch GitHub Actions bumps
- 14-day minimumReleaseAge across all ecosystems for supply
  chain protection (with strict internal checks so PRs are
  only opened after the stability window)

The Mend Renovate GitHub App must be installed on the repo
separately for this config to take effect.
2026-04-07 00:21:45 +01:00
.github/workflows chore: switch from dependabot to renovate 2026-04-07 00:21:45 +01:00
cmd/tint fix: resolve lint and go.mod tidy issues 2026-04-07 00:21:40 +01:00
internal Initial commit 2026-04-06 23:44:14 +01:00
.editorconfig Initial commit 2026-04-06 23:44:14 +01:00
.gitignore Initial commit 2026-04-06 23:44:14 +01:00
.golangci.yml Initial commit 2026-04-06 23:44:14 +01:00
go.mod fix: resolve lint and go.mod tidy issues 2026-04-07 00:21:40 +01:00
go.sum Initial commit 2026-04-06 23:44:14 +01:00
Justfile Initial commit 2026-04-06 23:44:14 +01:00
README.md Initial commit 2026-04-06 23:44:14 +01:00
register.go Initial commit 2026-04-06 23:44:14 +01:00
registry.go Initial commit 2026-04-06 23:44:14 +01:00
renovate.json chore: switch from dependabot to renovate 2026-04-07 00:21:45 +01:00
tint.go Initial commit 2026-04-06 23:44:14 +01:00
tint_test.go Initial commit 2026-04-06 23:44:14 +01:00

tint

Apply visual shaders — colour, animation, character substitution — to text in your terminal. Tint is a small Go library and CLI that treats a block of text as a 2D grid of cells and lets a "shader" decide how each cell should be rendered as truecolor ANSI.

CLI

echo "HELLO" | tint rainbow
figlet "FIRE" | tint fire --fps 30
echo "HELLO" | tint matrix --once > frame.ans

By default, tint animates when stdout is a terminal (looping until Ctrl-C or --timeout) and renders a single frame otherwise. That means piping to a file, pager, or another command gives you one clean frame without extra flags, while running interactively Just Works.

Built-in shaders:

Shader Description
rainbow Horizontal hue gradient that shifts across frames
fire Warm vertical gradient with animated shimmer
matrix Parallax katakana rain on multiple depth planes
solid A single foreground colour

Flags:

  --once          render a single frame and exit, even on a terminal
  --animate       force animation even when stdout is not a terminal
                  (useful for streaming frames to another tool)
  --fps N         animation frame rate (default: 10)
  --timeout N     stop animation after N seconds (default: no limit)
  --pad N         add N cells of margin around the text

--once and --animate are mutually exclusive.

Library

import "github.com/ryanlewis/tint"

func main() {
    _ = tint.Apply(os.Stdout, "HELLO\nWORLD", "rainbow", 0)
}

A shader is anything that implements the Shader interface:

type Shader interface {
    Shade(Cell) Output
}

Cell carries the rune, its grid coordinates, the grid dimensions and the current animation frame. Output is what the shader decides for that cell: the (possibly substituted) rune, foreground and background colours, and a style bitfield (bold, italic, underline, etc.).

Register a custom shader once and it becomes available to both the library and the CLI:

tint.Register("invert", func(w, h int) tint.Shader {
    return invertShader{}
})

Install

go install github.com/ryanlewis/tint/cmd/tint@latest

Or build from source:

just build

Development

just            # list targets
just test       # run tests
just lint       # run golangci-lint
just ci         # lint + test + build

License

MIT