All specs
Display · table

Table

Typed columns and rows. The structured data display.

Anatomy

Borderless (default):

NAME          STATUS    REGION     UPTIME  CPU %
web-frontend  running   us-east-1  3d 4h      12
api-server    running   us-east-1  3d 4h      38
worker-queue  starting  eu-west-1  32s         4
billing-svc   failed    us-east-1  0s          0

With borders:

╭──────────────┬──────────┬───────────┬────────┬───────╮
│ NAME         │ STATUS   │ REGION    │ UPTIME │ CPU % │
├──────────────┼──────────┼───────────┼────────┼───────┤
│ web-frontend │ running  │ us-east-1 │ 3d 4h  │    12 │
│ api-server   │ running  │ us-east-1 │ 3d 4h  │    38 │
│ worker-queue │ starting │ eu-west-1 │ 32s    │     4 │
│ billing-svc  │ failed   │ us-east-1 │ 0s     │     0 │
╰──────────────┴──────────┴───────────┴────────┴───────╯

Headers are accent + bold. Body rows use the terminal default foreground.

---

Options

type TableOptions<T> = {
  columns: ReadonlyArray<{
    header: string
    accessor: (row: T) => string | number | boolean
    align?: 'left' | 'right' | 'center'
    width?: number       // auto-fit if omitted
    truncate?: boolean   // ellipsize content > width
  }>
  rows: ReadonlyArray<T>
  showHeader?: boolean   // default: true
  borders?: boolean      // default: false
  gap?: number           // default: 2 (borderless gap)
  theme?: PartialTheme
}

---

Do & don't

Do

Use for tabular data with consistent columns (deploys, processes, files, users)

Right-align numeric columns (align: 'right')

Use truncate: true for columns that may have long content

Provide a typed T for the row shape — accessors get type safety

Don't

Don't use a table for two columns of label/value — use keyValue

Don't use borders: true in piped output — borders look bad in logs

Don't render thousands of rows at once — paginate yourself

Don't put rich/multiline content in cells — cells are single-line

---

Out of scope

Sortable / filterable — caller pre-sorts

Pagination — caller slices

Cell wrapping (multi-line cells) — single line only

Footer / totals row — caller composes a second mini-table

Sticky headers in scrolling output — terminal can't do that