layoutz

Zero-dependency library for terminal animations, compositional ANSI strings, plots, and Elm-style TUIs. In Scala, Haskell, and OCaml.

scala haskell ocaml

import layoutz._

val demo = layout(
  row(
    "Layoutz".style(Style.Bold),
    underline("^", Color.Cyan)("DEMO")
  ).center(),
  br,
  row(
    statusCard("Users", "1.2K"),
    statusCard("API", "UP").border(Border.Double),
    statusCard("CPU", "23%").border(Border.Thick).color(Color.Red),
    table(
      Seq("Name", "Role", "Skills"),
      Seq(
        Seq("Gegard", "Pugilist",
          ul("Armenian", ul("bad", ul("man")))),
        Seq("Eve", "QA", "Testing")
      )
    ).border(Border.Round).style(Style.Reverse)
  )
)

demo.putStrLn

Showcase

src: scala | haskell | ocaml

Inline animations

src: scala | haskell | ocaml

Interactive TUIs

scala haskell ocaml

import layoutz._

object CounterApp extends LayoutzApp[Int, String] {
  def init = (0, Cmd.none)

  def update(msg: String, count: Int) = msg match {
    case "inc" => (count + 1, Cmd.none)
    case "dec" => (count - 1, Cmd.none)
    case _     => (count, Cmd.none)
  }

  def subscriptions(count: Int) =
    Sub.onKeyPress {
      case Key.Char('+') => Some("inc")
      case Key.Char('-') => Some("dec")
      case _             => None
    }

  def view(count: Int) = layout(
    section("Counter")(s"Count: $count"),
    br,
    ul("Press `+` or `-`")
  )

}

CounterApp.run

Links

GitHub


© 2025–2026 Matthieu Court