💡 Motivation

Why terminal palette switching should be one command, not a project

The Problem

Changing your terminal's color palette has always been more painful than it should be. Most solutions require you to dig through your terminal's preferences GUI, install a theme manager with its own dependencies, source a shell script, restart the terminal, or — if you use Alacritty — edit a YAML file and restart.

None of these work across terminals. None of them are one command. None of them let you instantly try 420 palettes to see which one feels right right now.

Your editor theme and your terminal palette should be as easy to switch as a radio station.

Before pal

  • Find a theme script online
  • Figure out where to put it
  • source it, maybe restart terminal
  • One theme per script
  • Break on different shells
  • No easy way to explore

With pal

  • One binary, works everywhere
  • pal dracula-dark — done
  • Takes effect immediately
  • 420 palettes to explore
  • Works in any terminal
  • pal random to discover
The Insight: OSC Sequences

Modern terminal emulators support OSC (Operating System Command) escape sequences — a standard mechanism to set colors at runtime, without any terminal-specific plugins or config. Write the right bytes to stdout, and your terminal recolors immediately.

\033]4;1;#FF5555\033\ sets color slot 1 (red) to Dracula's red. \033]11;#282A36\033\ sets the background. That's all palette switching is — 19 of these sequences.

This works in xterm, VTE-based terminals (GNOME Terminal, Tilix), iTerm2, Kitty, Alacritty, WezTerm, and virtually any terminal built in the last decade.

The Palette Data: c_palettes

c_palettes is a C project with an outstanding collection of curated terminal palettes in two formats: the simple 19-line paleta format and the kfc key=value format. 420 palettes total, covering everything from Base16 variants to designer series to editor themes.

Rather than build another C tool, the goal was to take that same palette data and package it in the most frictionless possible way: embed it in a Go binary at compile time with //go:embed, ship a single file, require nothing else.

Why Go

Go's //go:embed directive lets you bake arbitrary files into the binary at compile time — no separate asset bundler, no runtime file loading, no install directory. 420 palette files totaling ~130 KB are compiled directly into the 2.5 MB binary.

Go also produces static, self-contained binaries with zero runtime dependencies. CGO_ENABLED=0 go build gives you a binary you can copy to any Linux machine and run immediately — no Go runtime, no libc, nothing.

//go:embed palette data baked in at compile time
CGO_ENABLED=0 fully static, no libc
-trimpath -ldflags="-s -w" small, stripped binary
Philosophy
A tool that does one thing should be one file. No config, no install wizard, no dependencies to manage. Drop it in /usr/local/bin and it works — forever.

pal has no configuration file. It has no plugin system. It doesn't try to persist your choice across terminal sessions (use pal export + your shell profile for that). It doesn't integrate with your editor or your window manager.

It switches your terminal's color palette. That's it. That's the whole tool. And it does it instantly, with 420 choices, from a 2.5 MB binary with zero dependencies.