Spectrum provides ANSI color and style formatting integrated with OCaml's Format module using semantic tags. It supports named colours from the xterm 256-color palette, CSS-style hex codes, and RGB or HSL values.
Terminal capabilities are detected automatically and colours are quantized to the nearest match using LAB color space distance.
opam install spectrum
Spectrum.Simple.printf "@{<green>Hello@} @{<bold>world@}!@."getting_started — Install Spectrum, write your first colored output, learn the tag syntax step by step.
The pattern is @{<TAG-NAME>CONTENT@}. Tags are case-insensitive and can be nested arbitrarily.
@{<green>text@}, @{<dark-orange>text@} — all 256 xterm color names@{<#f0c090>text@}, @{<#f00>text@} — CSS-style 3 or 6 digit hex codes@{<rgb(240 192 144)>text@} — CSS-style with optional commas@{<hsl(60 100 50)>text@} — hue (degrees), saturation, lightness; % sign optionalbold, dim, italic, underline, blink, rapid-blink, inverse, hidden, strikethru, overline
@{<bg:#f00>text@}@{<fg:blue>text@}@{<bold,bg:red,yellow>text@} — comma-separated listcustom_palettes — Define a custom palette for terminals with non-standard color mappings (advanced, rarely needed)color_quantization — How Spectrum matches colors to terminal capabilities, why LAB color space, the package architectureSpectrum provides two module variants:
Spectrum.Exn — raises exceptions on invalid color/style tagsSpectrum.Noexn — silently ignores invalid tags (default, also available as just Spectrum)Both expose the same interface:
val prepare_ppf : Format.formatter -> unit -> unit
module Simple : sig
val printf : ('a, Format.formatter, unit, unit) format4 -> 'a
val eprintf : ('a, Format.formatter, unit, unit) format4 -> 'a
val sprintf : ('a, Format.formatter, unit, string) format4 -> 'a
endSpectrum.Simple.printf handles formatter setup/teardown automatically. For repeated printing, use Spectrum.prepare_ppf with the standard Format functions.
For programmatic (non-string) tag construction, see Spectrum.Stag.
Note: Format.sprintf uses its own buffer, so you must use Spectrum.Simple.sprintf for styled sprintf, or create your own buffer with Format.fprintf as described in the Format docs.
Spectrum detects terminal color support and quantizes accordingly:
let info = Spectrum.Capabilities.supported_color_levels () in
match info.stdout with
| True_color -> Printf.printf "24-bit color\n"
| Eight_bit -> Printf.printf "256 colors\n"
| Basic -> Printf.printf "16 colors\n"
| Unsupported -> Printf.printf "No color support\n"Override with FORCE_COLOR=0|1|2|3. See Spectrum_capabilities.Capabilities for details, or color_quantization for how quantization works.
Spectrum — Main library with formatting functionsSpectrum_capabilities — Terminal color capability detection (standalone, zero deps on rest of Spectrum)Spectrum_tools — Color conversion utilities and terminal queriesSpectrum_palettes — Pre-generated palette modules (Basic, Xterm256)Spectrum_palette_ppx — PPX extension for custom palette generation