Getting Started with Spectrum

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 Spectrum

Install the library from opam:

opam install spectrum

Set Up a Project

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.

Add Text Styles

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.

Use Hex and RGB Colors

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).

Nest and Combine Tags

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.

Use the Formatter API

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.

Handle Invalid Tags

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 ()

What You've Learned

You can now:

Next Steps