This tutorial walks you through adding colored terminal output to an OCaml program using Spectrum. By the end, you'll have a program that prints styled, colored text to the terminal.
Prerequisites: OCaml 4.14+ and opam installed.
Install the library from opam:
opam install spectrum
Create a new directory with a minimal dune-project and source file:
mkdir hello-spectrum && cd hello-spectrum
Create a dune-project file:
(lang dune 3.9)
Create a bin directory and add a dune file inside it:
mkdir bin
bin/dune:
(executable (name main) (libraries spectrum))
Create bin/main.ml with the following code:
let () =
Spectrum.Simple.printf "@{<green>Hello, Spectrum!@}@."Build and run:
dune exec bin/main.exe
You should see "Hello, Spectrum!" printed in green text. The @{<green>...@} syntax is a Format semantic tag — Spectrum uses it to inject ANSI color codes.
Spectrum supports ANSI text styles as well as colors. Edit bin/main.ml:
let () =
Spectrum.Simple.printf "@{<bold>Bold@} and @{<italic>italic@} text@.";
Spectrum.Simple.printf "@{<underline>Underlined@} and @{<dim>dimmed@} text@."Build and run again. You should see bold, italic, underlined, and dimmed text. The full list of styles: bold, dim, italic, underline, blink, rapid-blink, inverse, hidden, strikethru, overline.
Beyond named colors, Spectrum accepts CSS-style hex codes, RGB, and HSL values. Edit bin/main.ml:
let () =
Spectrum.Simple.printf "@{<#ff5733>Hex color@}@.";
Spectrum.Simple.printf "@{<#f00>Short hex (red)@}@.";
Spectrum.Simple.printf "@{<rgb(100 149 237)>Cornflower blue@}@.";
Spectrum.Simple.printf "@{<hsl(280 70 50)>Purple via HSL@}@."Build and run. Each line should appear in a different color. On terminals with limited color support, Spectrum automatically quantizes these to the nearest available color (see color_quantization).
Tags can be nested — inner tags add to the style stack and closing restores the previous style:
let () =
Spectrum.Simple.printf
"@{<green>Green text @{<bold>bold green@} back to green@}@."You can also combine multiple styles in a single tag using commas:
let () =
Spectrum.Simple.printf
"@{<bold,bg:red,yellow>Warning banner@}@."This sets bold text, a red background, and yellow foreground — all in one tag. Any color can be prefixed with bg: for background or fg: for explicit foreground.
Spectrum.Simple.printf is convenient for one-off printing. For repeated printing, it's more efficient to prepare a formatter once with Spectrum.prepare_ppf:
let () =
let reset = Spectrum.prepare_ppf Format.std_formatter in
Format.printf "@{<green>Line 1@}@.";
Format.printf "@{<blue>Line 2@}@.";
Format.printf "@{<red>Line 3@}@.";
reset ()The reset function restores the formatter to its original state. Use this pattern in applications where you print many colored lines.
By default, Spectrum silently ignores invalid tags. If you prefer to catch mistakes, use the Spectrum.Exn module:
let () =
let reset = Spectrum.Exn.prepare_ppf Format.std_formatter in
(try
Format.printf "@{<notacolor>This will raise@}@."
with Spectrum_palette_ppx.Palette.InvalidColorName name ->
Format.printf "Unknown color: %s@." name);
reset ()You can now:
custom_palettes — Create and use a custom color palettecolor_quantization — Understand how Spectrum matches colors to terminal capabilitiesSpectrum — Full API referenceSpectrum.Stag — Type-safe variant-based tags for programmatic use