Terminal styling and layout widgets for OCaml (tables, trees, panels, colors)
OCaml 96.9%
Standard ML 0.8%
Dune 0.6%
Other 1.7%
41 1 0

Clone this repository

https://tangled.org/gazagnaire.org/ocaml-tty https://tangled.org/did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-tty
git@git.recoil.org:gazagnaire.org/ocaml-tty git@git.recoil.org:did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-tty

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

tty#

Terminal styling and layout widgets for OCaml CLI applications.

╭──────────────────────────────────────────────────────────────────╮
│                                                                  │
│   ████████╗████████╗██╗   ██╗                                    │
│   ╚══██╔══╝╚══██╔══╝╚██╗ ██╔╝                                    │
│      ██║      ██║    ╚████╔╝                                     │
│      ██║      ██║     ╚██╔╝                                      │
│      ██║      ██║      ██║                                       │
│      ╚═╝      ╚═╝      ╚═╝                                       │
│                                                                  │
│   Type-safe terminal styling and layout widgets for OCaml        │
│                                                                  │
╰──────────────────────────────────────────────────────────────────╯

What it looks like#

Tables#

╭──────────┬────────┬─────────┬──────────┬─────────┬───────────╮
│ Target   │ Inst.  │ Execs   │ Paths    │ Crashes │ Exec/s    │
├──────────┼────────┼─────────┼──────────┼─────────┼───────────┤
│ cbort    │      3 │    1.2M │      847 │       0 │     4,521 │
│ yamlrw   │      3 │    890K │    1,203 │       2 │     3,102 │
│ jsonwt   │      2 │    2.1M │      412 │       0 │     6,847 │
╰──────────┴────────┴─────────┴──────────┴─────────┴───────────╯

Trees#

src
├── lib
│   ├── tty.ml
│   ├── style.ml
│   └── table.ml
├── bin
│   └── main.ml
└── test
    └── test_tty.ml

Panels#

╭─────────────────────── Status ───────────────────────╮
│                                                      │
│  ✓ All systems operational                           │
│  ✓ Database connected                                │
│  ✓ Cache warmed                                      │
│                                                      │
╰──────────────────────────────────────────────────────╯

Border Styles#

ASCII:            Single:           Rounded:          Heavy:
+-------+         ┌───────┐         ╭───────╮         ┏━━━━━━━┓
| hello |         │ hello │         │ hello │         ┃ hello ┃
+-------+         └───────┘         ╰───────╯         ┗━━━━━━━┛

Double:
╔═══════╗
║ hello ║
╚═══════╝

Features#

  • Composable styles: Style.(bold + fg Color.red + underline)
  • Full color support: ANSI 16, 256-color palette, true color (RGB/hex)
  • Tables: Headers, alignment, multiple border styles
  • Trees: Directory-style tree rendering with guides
  • Panels: Bordered boxes with titles
  • Unicode-aware: Proper width calculation for CJK and emoji

Installation#

opam install tty

Quick Start#

Styled Text#

open Tty

(* Compose styles with + *)
let success = Style.(bold + fg Color.green)
let error = Style.(bold + fg Color.red)
let warning = Style.(fg Color.yellow)

let () =
  Fmt.pr "%a@." (Style.styled success Fmt.string) "✓ Build passed";
  Fmt.pr "%a@." (Style.styled error Fmt.string) "✗ Tests failed";
  Fmt.pr "%a@." (Style.styled warning Fmt.string) "⚠ Deprecation warning"

Tables#

open Tty

let () =
  let table = Table.(
    of_rows ~border:Border.rounded
      [ column "Name"; column ~align:`Right "Size"; column "Modified" ]
      [
        [ Span.text "README.md"; Span.text "2.4K"; Span.text "2 hours ago" ];
        [ Span.text "src/"; Span.text "4.0K"; Span.text "yesterday" ];
        [ Span.text "Makefile"; Span.text "892"; Span.text "3 days ago" ];
      ]
  ) in
  Table.pp Format.std_formatter table

Output:

╭───────────┬──────┬─────────────╮
│ Name      │ Size │ Modified    │
├───────────┼──────┼─────────────┤
│ README.md │ 2.4K │ 2 hours ago │
│ src/      │ 4.0K │ yesterday   │
│ Makefile  │  892 │ 3 days ago  │
╰───────────┴──────┴─────────────╯

Trees#

open Tty

let () =
  let tree = Tree.of_tree (
    Node (Span.text "myproject", [
      Node (Span.text "src", [
        Node (Span.text "main.ml", []);
        Node (Span.text "lib.ml", []);
      ]);
      Node (Span.text "test", [
        Node (Span.text "test_main.ml", []);
      ]);
      Node (Span.text "dune-project", []);
    ])
  ) in
  Tree.pp Format.std_formatter tree

Output:

myproject
├── src
│   ├── main.ml
│   └── lib.ml
├── test
│   └── test_main.ml
└── dune-project

Panels#

open Tty

let () =
  let panel = Panel.create
    ~border:Border.rounded
    ~title:(Span.text "Summary")
    (Span.text "Processed 1,234 files\nFound 42 issues\nFixed 38 automatically")
  in
  Panel.pp Format.std_formatter panel

Output:

╭─────────────────────── Summary ────────────────────────╮
│ Processed 1,234 files                                  │
│ Found 42 issues                                        │
│ Fixed 38 automatically                                 │
╰────────────────────────────────────────────────────────╯

Colors#

open Tty

(* ANSI 16 colors *)
let red = Color.red
let bright_blue = Color.bright_blue

(* RGB colors *)
let coral = Color.rgb 255 127 80
let teal = Color.rgb 0 128 128

(* Hex colors *)
let purple = Color.hex "#8B5CF6"
let orange = Color.hex "F97316"

(* 256-color palette *)
let pink = Color.palette 213

(* Use in styles *)
let gradient_style = Style.(fg coral + bg (Color.rgb 30 30 30))

Styles#

Available style attributes:

Attribute Example
bold bold text
faint dimmed text
italic italic text
underline underlined text
blink blinking text
reverse inverted colors
strikethrough strikethrough
fg color coloured foreground
bg color coloured background
(* Combine any attributes *)
let fancy = Style.(bold + italic + underline + fg Color.cyan + bg Color.black)

API Reference#

Module Description
Tty.Color ANSI, RGB, hex, and 256-palette colors
Tty.Style Composable text styles
Tty.Span Styled text spans
Tty.Border Border styles (ascii, single, double, rounded)
Tty.Table Tables with headers and alignment
Tty.Tree Tree rendering with guides
Tty.Panel Bordered panels with titles
Tty.Width Unicode-aware string width calculation
  • Rich - Python library for rich text and beautiful formatting. Primary inspiration.
  • lipgloss - Go library for terminal styling. Inspiration for composable style API.
  • printbox - OCaml library for printing nested boxes, tables and trees.
  • progress - Terminal progress bars for OCaml.
  • notty - OCaml library for declarative terminal graphics.

Licence#

MIT License. See LICENSE.md for details.