tablewriter

A Go library for rendering rich ASCII, Unicode, Markdown, HTML, and colorized tables, with streaming support for large datasets.

Library
Go
vv1.1.5
4,821 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
83 /100 Excellent
Development Activity 96
Maintenance 72
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
75 /100 Good
Architecture 78
Code Quality 82
Innovation 74
Learning Curve 65

tablewriter is a Go library for turning slices, structs, and CSV data into formatted tables. It ships multiple renderers — ASCII (Blueprint), Unicode, Markdown, HTML, SVG, and ANSI-colorized — behind a single API, so the same table data can target a terminal, a Markdown doc, or a web page just by swapping the renderer.

Beyond basic rendering it supports cell merging, per-section (header/row/footer) alignment and padding, Unicode-aware column widths for CJK and emoji content, struct-tag driven population with generics, and a streaming mode (the Ocean renderer) for writing very large tables incrementally instead of buffering everything in memory. Configuration is handled through a large set of composable functional options (With*()), letting callers override borders, symbols, filters, and callbacks at global or per-column granularity.

What You Get

  • A Table type built via NewTable/NewWriter that accepts headers, rows, and footers from slices, structs (via tw struct tags), or CSV readers
  • Six renderers out of the box — Blueprint (ASCII), Markdown, HTML, Colorized, Ocean (streaming), and SVG — swappable without changing how data is added
  • A streaming mode for rendering large datasets row-by-row without buffering the whole table
  • Cell merging, per-section alignment/padding/filters, and custom border symbol sets configurable through With*() functional options
  • Unicode-aware width calculation (via grapheme segmentation) so CJK characters and emoji don’t break column alignment
  • A companion csv2table CLI in cmd/ for converting CSV files to formatted tables from the command line

Common Use Cases

  • CLI tool output - Developers building command-line tools format structured data (status reports, diffs, inventories) as readable terminal tables.
  • Log and report formatting - Backend services render tabular summaries (job results, test reports) as Markdown or HTML for docs and dashboards.
  • CSV to table conversion - Data pipelines and admin scripts import CSV files directly via NewCSVReader/NewCSV and render them as formatted output.
  • Database result display - Applications with sql.Null* support print query results directly as terminal tables without manual null-handling.

Under The Hood

Architecture

A Table struct holds row/header/footer data as [][]string alongside computed column widths and a pluggable tw.Renderer interface implementation (Blueprint, HTML, Markdown, Colorized, Ocean, SVG all live under renderer/). Rendering runs through an internal renderContext/mergeContext pair that tracks per-section widths, merge state, and visible-column counts before handing lines to the active renderer, keeping layout computation separate from output formatting. Shared low-level types (Mapper, CellConfig, Position, MergeState) live in the tw/ package, while pkg/twwidth, pkg/twcache, and pkg/twwarp isolate Unicode width measurement, reflection-stringer caching, and text wrapping as independent, individually testable units. Streaming mode (stream.go) carries its own state (streamWidths, streamRowCounter, lastRenderedLineContent) so the Ocean renderer can emit rows incrementally without buffering the full table, and a large option.go exposes dozens of With*() functional options as the sole mutation surface into Config.

Tech Stack

Written in Go 1.21 with a deliberately small dependency footprint: clipperhouse/displaywidth and clipperhouse/uax29/v2 for Unicode grapheme segmentation and display-width math, mattn/go-runewidth as a secondary width source, fatih/color for ANSI terminal coloring, and olekukonko/errors plus olekukonko/ll for typed errors and structured debug logging. There’s no web framework, ORM, or database driver in the dependency graph — this is a pure formatting library, built with the standard go build/go test toolchain and distributed as an importable module (plus a small cmd/csv2table CLI built on top of it).

Code Quality

Test coverage is extensive: 23 _test.go files, including 15 top-level test functions in tablewriter_test.go and a dedicated tests/ directory covering blueprint, markdown, HTML, colorized, streaming, merge, struct, CSV, and SVG rendering paths, plus benchmark files for width calculation and caching. A .golangci.yml enforces linting, and GitHub Actions runs go build and go test -v ./... on every push and pull request to master. Errors are surfaced through a typed errors package and an ll structured logger rather than swallowed, and package boundaries (pkg/twwidth, pkg/twcache, pkg/twwarp) keep low-level concerns unit-testable in isolation.

What Makes It Unique

Most ASCII table libraries stop at fixed-width columns and a single output format; tablewriter unifies six renderers (ASCII, Unicode, Markdown, HTML, SVG, ANSI-colorized) behind one data-population API, adds a genuine streaming renderer for datasets too large to buffer, and uses real Unicode grapheme segmentation rather than naive rune counting to keep columns aligned across CJK text and emoji. Struct-tag driven population with generics support and a comprehensive functional-options system for per-section (header/row/footer) and per-column overrides give it a configuration surface closer to a rendering engine than a simple formatting helper.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers