nekrassov01/table

A high-performance table rendering library for Go

1

stars

33

commits

Go

primary language

Sep 11, 2026

updated

pkg.go.dev/github.com/nekrassov01/table
ascii
backlog
csv
go
markdown
streaming
table
unicode

README

table logo

TABLE

A high-performance table rendering library for Go, with streaming APIs for every output format.

CI Go Reference License

Table of contents

Overview

nekrassov01/table renders Go data as terminal tables, markup tables, or CSV records. Each output package provides Table for complete data sets and Stream for row-at-a-time output while retaining the selected format's own structure and escaping rules.

See Runnable examples for a generated catalog of inputs, options, commands, and exact output.

  • table uses functional options for clear, reusable configuration.
  • In the bundled comparisons, table runs 5.9 to 7.0 times as fast as the next-fastest alternative; see Performance.
  • table reuses internal buffers to minimize steady-state allocations.
  • TableOf and StreamOf adapt typed slices and error-returning iterators.
  • text measures Unicode by terminal display width, including ambiguous character widths in CJK locales.
  • Format-specific options add headers, calculated footers, indexes, placeholders, transformations, alignment, decoration, and cell spans.

Motivation

The project was created for four reasons:

  • To provide a table renderer that is fast, efficient, and easy to use.
  • To provide row-at-a-time output across every format, which no comparable library offered at the time.
  • To manage table-oriented output formats for applications such as CLIs in one module.
  • To support the less common Backlog table notation, which only the author's earlier mintab project covered at the time.

Output formats

Choose an output package for the destination. The root table package provides shared interfaces, typed row adapters, and errors; it does not select an output format.

PackageOutputUse it for
textUnicode or ASCII bordered tablesCLIs, terminals, and logs
htmlSemantic HTML tablesWeb pages and reports
markdownGFM tablesREADMEs and GitHub
backlogBacklog table notationBacklog issues and Wiki pages
csvCSV records with a configurable delimiterTSV, CSV, and data interchange

The examples below show the text package in several configurations.

ASCII

ASCII table

Simple

Simple table

Compact layout with horizontal lines omitted and a colored rounded border style

Compact table

Row spans with a colored heavy border style

Table with row spans

Column spans with a colored light border style

Table with column spans

Stacked header with a colored light border style

Table with a stacked header

Calculated footer with CJK text and a colored light border style

Table with a calculated footer

Calculated footer with CJK text, value transformations, and a colored light border style

Table with transformed values

Complex values with a colored double border style

Table containing complex values

Installation

Install with:

go get github.com/nekrassov01/table

Quick start

TableOf and StreamOf adapt typed application data to the rows accepted by every output package.

Table

Use TableOf to keep application data typed until the row boundary. This example renders deployment status to a terminal.

package main

import (
    "log"
    "os"

    "github.com/nekrassov01/table"
    "github.com/nekrassov01/table/text"
)

type Deployment struct {
    Service string
    Desired int
    Ready   int
    Status  string
}

func deploymentRow(deployment Deployment) []any {
    return []any{
        deployment.Service,
        deployment.Desired,
        deployment.Ready,
        deployment.Status,
    }
}

func main() {
    deployments := []Deployment{
        {Service: "payments", Desired: 4, Ready: 4, Status: "healthy"},
        {Service: "search", Desired: 3, Ready: 2, Status: "degraded"},
        {Service: "worker", Desired: 8, Ready: 8, Status: "healthy"},
    }

    output := text.NewTable(os.Stdout,
        text.WithHeader([]string{"SERVICE", "DESIRED", "READY", "STATUS"}),
        text.WithAlign(text.ScopeBody, text.Columns(1, 2), text.AlignRight),
        text.WithCompact(),
    )
    if err := output.Render(table.TableOf(deployments, deploymentRow)); err != nil {
        log.Fatal(err)
    }
}

This program produces the following table:

┌──────────┬─────────┬───────┬──────────┐
│ SERVICE  │ DESIRED │ READY │  STATUS  │
╞══════════╪═════════╪═══════╪══════════╡
│ payments │       4 │     4 │ healthy  │
│ search   │       3 │     2 │ degraded │
│ worker   │       8 │     8 │ healthy  │
└──────────┴─────────┴───────┴──────────┘

Stream

Use StreamOf to adapt an iter.Seq2[T, error] to streaming table rows. Each successful value becomes one output row, and the first source error is forwarded. Call Stream.Close even after an earlier error so it can attempt deferred output and release its internal workspace.

package report

import (
    "io"
    "iter"
    "time"

    "github.com/nekrassov01/table"
    "github.com/nekrassov01/table/text"
)

type AuditEvent struct {
    Time     time.Time
    Actor    string
    Action   string
    Resource string
}

func WriteAuditEvents(w io.Writer, events iter.Seq2[AuditEvent, error]) (err error) {
    output := text.NewStream(w,
        text.WithHeader([]string{"TIME", "ACTOR", "ACTION", "RESOURCE"}),
        text.WithCompact(),
    )
    defer func() {
        if closeErr := output.Close(); err == nil {
            err = closeErr
        }
    }()

    rows := table.StreamOf(events, func(event AuditEvent) []any {
        return []any{
            event.Time.Format(time.RFC3339),
            event.Actor,
            event.Action,
            event.Resource,
        }
    })
    for row, sourceErr := range rows {
        if sourceErr != nil {
            return sourceErr
        }
        if renderErr := output.Render(row); renderErr != nil {
            return renderErr
        }
    }
    return nil
}

Given an iterator of audit events, the function produces output like this:

┌───────────────────────────┬────────────┬───────────┬──────────────┐
│           TIME            │   ACTOR    │  ACTION   │   RESOURCE   │
╞═══════════════════════════╪════════════╪═══════════╪══════════════╡
│ 2026-08-21T09:00:00+09:00 │ deploy-bot │ reconcile │ payments-api │
│ 2026-08-21T09:03:00+09:00 │ alice      │ scale     │ worker       │
│ 2026-08-21T09:08:00+09:00 │ bob        │ rollback  │ search-api   │
└───────────────────────────┴────────────┴───────────┴──────────────┘

Runnable examples

The generated examples catalog pairs shared input data with the exact options, commands, and output for every supported scenario. The same definitions drive the catalog, runnable examples, and benchmarks.

Use target, mode, and data to select the output package, API, and scenario. This command runs the simple text Table example:

make example target=text mode=table data=simple

Omit data to run every scenario for the selected package and mode. With no data selected, omit mode to run both APIs, or run make example without arguments to run every available example.

Table library comparison

The following tables compare the public APIs in the versions pinned by the benchmark module.

Formats

This table records the output implementations documented by each library. means the library provides a dedicated output mode for the format, and - means it does not. table targets the GFM table extension; the other Markdown entries indicate generic Markdown table output.

Output formattablego-pretty v6.8.3tablewriter v1.1.4simpletable v1.0.0
Text
HTML-
Markdown
Backlog notation---
CSV or TSV--
SVG---

Features

This table records whether each library exposes a direct public API for a capability in at least one output implementation. It does not imply that every format can express the capability.

Featuretablego-pretty v6.8.3tablewriter v1.1.4simpletable v1.0.0
Streaming API✓ (All)--
Header
Footer
Placeholder✓ (HTML)--
Index column--
Vertical merge-
Horizontal merge
Caller-defined row adapter--
Reflection-based struct input---
CSV input---
Per-column transformation-
Built-in sorting and filtering---
Pagination---
Column hiding--
Width, wrapping, and truncation-
Automatic terminal fit---
Title or caption-
Pluggable output implementation---

For table, the feature matrix has the following qualifications:

  • Footer callbacks derive values such as totals and averages from captured state.
  • Column hiding is intentionally left to input adaptation, so TableOf and StreamOf can omit fields before rows reach the output package.
  • Merge behavior depends on the selected output format and is documented in the Public API guide.

The go-pretty placeholder entry refers to its HTML EmptyColumn setting.

Performance

[!NOTE] table is designed to minimize allocations and reuses internal buffers via sync.Pool. In steady-state benchmarks, common workloads reach one allocation per render; cold runs require additional allocations to initialize pooled state.

Run make bench target=comparison benchtime=1x count=1 to reduce steady-state amortization and expose one-iteration setup costs. For explicit pool-drained measurements of table, run make bench target=cold.

Run the comparison on your machine with make bench target=comparison. The following output records all five samples on an Apple M2 with Go 1.27.0:

$ make bench target=comparison
go test -benchmem -count 5 -benchtime 10000x -cpuprofile cpu.prof -memprofile mem.prof . -bench '^BenchmarkComparison'
goos: darwin
goarch: arm64
pkg: benchmarks
cpu: Apple M2
BenchmarkComparisonTableSimple-8           10000        2436 ns/op       225 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1847 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1739 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1804 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1773 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       10580 ns/op      8155 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       10572 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       11115 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       11826 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       10688 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       81974 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       79278 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       81598 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       87737 ns/op    486949 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       80748 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       23490 ns/op     13109 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       23955 ns/op     13098 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       22876 ns/op     13121 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       22583 ns/op     13116 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       22650 ns/op     13098 B/op       425 allocs/op
BenchmarkComparisonTableComplex-8          10000        9192 ns/op      1150 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9158 ns/op      1150 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9176 ns/op      1149 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9128 ns/op      1149 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9106 ns/op      1150 B/op        35 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       63998 ns/op     49260 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       63791 ns/op     49260 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       61935 ns/op     49263 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       64352 ns/op     49261 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       62202 ns/op     49261 B/op       317 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      276792 ns/op    720005 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      280501 ns/op    719999 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      277848 ns/op    720000 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      278027 ns/op    719994 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      279195 ns/op    719997 B/op      4749 allocs/op
PASS
ok      benchmarks      24.222s

The table summarizes those five samples. Each cell shows allocs/op · ns/op; both values are medians.

Scenariotablego-prettytablewritersimpletable
Simple1 · 1,804110 · 10,688973 · 81,598425 · 22,876
Complex values35 · 9,158317 · 63,7914,749 · 278,027-

- indicates that a library cannot express the scenario with the benchmark input.

The comparison benchmark uses the shared Simple and Complex data sets. Static data is converted to each library's required row type before timing begins. Each timed iteration constructs a table, processes the rows, and writes the result to a reused buffer. Complex compares native value handling rather than equivalent rendered bytes.

The benchmark preserves each library's configuration model: table uses only functional options, go-pretty accumulates settings through setters, tablewriter combines constructor options with methods, and simpletable receives prebuilt cells through exposed table sections. These native construction paths remain inside each timed iteration. Only the settings needed to align table structure and preserve header text are applied; border characters and value formatting retain each library's defaults.

Documentation

Use these references to select the API, understand its design, and work on the module itself.

ResourceContents
Go ReferenceExact declarations and symbol documentation
Public API guideOptions, output behavior, defaults, and format capabilities
ArchitecturePackage structure, data flow, and state ownership
Design specificationDesign decisions, invariants, tradeoffs, and non-goals
Development guideTest, benchmark, coverage, and analysis commands
Performance baselineBenchmark procedure and performance acceptance criteria

Author

nekrassov01

License

MIT

Contributors

nekrassov01/table

A high-performance table rendering library for Go

1

stars

33

commits

Go

primary language

Sep 11, 2026

updated

pkg.go.dev/github.com/nekrassov01/table
ascii
backlog
csv
go
markdown
streaming
table
unicode

README

table logo

TABLE

A high-performance table rendering library for Go, with streaming APIs for every output format.

CI Go Reference License

Table of contents

Overview

nekrassov01/table renders Go data as terminal tables, markup tables, or CSV records. Each output package provides Table for complete data sets and Stream for row-at-a-time output while retaining the selected format's own structure and escaping rules.

See Runnable examples for a generated catalog of inputs, options, commands, and exact output.

  • table uses functional options for clear, reusable configuration.
  • In the bundled comparisons, table runs 5.9 to 7.0 times as fast as the next-fastest alternative; see Performance.
  • table reuses internal buffers to minimize steady-state allocations.
  • TableOf and StreamOf adapt typed slices and error-returning iterators.
  • text measures Unicode by terminal display width, including ambiguous character widths in CJK locales.
  • Format-specific options add headers, calculated footers, indexes, placeholders, transformations, alignment, decoration, and cell spans.

Motivation

The project was created for four reasons:

  • To provide a table renderer that is fast, efficient, and easy to use.
  • To provide row-at-a-time output across every format, which no comparable library offered at the time.
  • To manage table-oriented output formats for applications such as CLIs in one module.
  • To support the less common Backlog table notation, which only the author's earlier mintab project covered at the time.

Output formats

Choose an output package for the destination. The root table package provides shared interfaces, typed row adapters, and errors; it does not select an output format.

PackageOutputUse it for
textUnicode or ASCII bordered tablesCLIs, terminals, and logs
htmlSemantic HTML tablesWeb pages and reports
markdownGFM tablesREADMEs and GitHub
backlogBacklog table notationBacklog issues and Wiki pages
csvCSV records with a configurable delimiterTSV, CSV, and data interchange

The examples below show the text package in several configurations.

ASCII

ASCII table

Simple

Simple table

Compact layout with horizontal lines omitted and a colored rounded border style

Compact table

Row spans with a colored heavy border style

Table with row spans

Column spans with a colored light border style

Table with column spans

Stacked header with a colored light border style

Table with a stacked header

Calculated footer with CJK text and a colored light border style

Table with a calculated footer

Calculated footer with CJK text, value transformations, and a colored light border style

Table with transformed values

Complex values with a colored double border style

Table containing complex values

Installation

Install with:

go get github.com/nekrassov01/table

Quick start

TableOf and StreamOf adapt typed application data to the rows accepted by every output package.

Table

Use TableOf to keep application data typed until the row boundary. This example renders deployment status to a terminal.

package main

import (
    "log"
    "os"

    "github.com/nekrassov01/table"
    "github.com/nekrassov01/table/text"
)

type Deployment struct {
    Service string
    Desired int
    Ready   int
    Status  string
}

func deploymentRow(deployment Deployment) []any {
    return []any{
        deployment.Service,
        deployment.Desired,
        deployment.Ready,
        deployment.Status,
    }
}

func main() {
    deployments := []Deployment{
        {Service: "payments", Desired: 4, Ready: 4, Status: "healthy"},
        {Service: "search", Desired: 3, Ready: 2, Status: "degraded"},
        {Service: "worker", Desired: 8, Ready: 8, Status: "healthy"},
    }

    output := text.NewTable(os.Stdout,
        text.WithHeader([]string{"SERVICE", "DESIRED", "READY", "STATUS"}),
        text.WithAlign(text.ScopeBody, text.Columns(1, 2), text.AlignRight),
        text.WithCompact(),
    )
    if err := output.Render(table.TableOf(deployments, deploymentRow)); err != nil {
        log.Fatal(err)
    }
}

This program produces the following table:

┌──────────┬─────────┬───────┬──────────┐
│ SERVICE  │ DESIRED │ READY │  STATUS  │
╞══════════╪═════════╪═══════╪══════════╡
│ payments │       4 │     4 │ healthy  │
│ search   │       3 │     2 │ degraded │
│ worker   │       8 │     8 │ healthy  │
└──────────┴─────────┴───────┴──────────┘

Stream

Use StreamOf to adapt an iter.Seq2[T, error] to streaming table rows. Each successful value becomes one output row, and the first source error is forwarded. Call Stream.Close even after an earlier error so it can attempt deferred output and release its internal workspace.

package report

import (
    "io"
    "iter"
    "time"

    "github.com/nekrassov01/table"
    "github.com/nekrassov01/table/text"
)

type AuditEvent struct {
    Time     time.Time
    Actor    string
    Action   string
    Resource string
}

func WriteAuditEvents(w io.Writer, events iter.Seq2[AuditEvent, error]) (err error) {
    output := text.NewStream(w,
        text.WithHeader([]string{"TIME", "ACTOR", "ACTION", "RESOURCE"}),
        text.WithCompact(),
    )
    defer func() {
        if closeErr := output.Close(); err == nil {
            err = closeErr
        }
    }()

    rows := table.StreamOf(events, func(event AuditEvent) []any {
        return []any{
            event.Time.Format(time.RFC3339),
            event.Actor,
            event.Action,
            event.Resource,
        }
    })
    for row, sourceErr := range rows {
        if sourceErr != nil {
            return sourceErr
        }
        if renderErr := output.Render(row); renderErr != nil {
            return renderErr
        }
    }
    return nil
}

Given an iterator of audit events, the function produces output like this:

┌───────────────────────────┬────────────┬───────────┬──────────────┐
│           TIME            │   ACTOR    │  ACTION   │   RESOURCE   │
╞═══════════════════════════╪════════════╪═══════════╪══════════════╡
│ 2026-08-21T09:00:00+09:00 │ deploy-bot │ reconcile │ payments-api │
│ 2026-08-21T09:03:00+09:00 │ alice      │ scale     │ worker       │
│ 2026-08-21T09:08:00+09:00 │ bob        │ rollback  │ search-api   │
└───────────────────────────┴────────────┴───────────┴──────────────┘

Runnable examples

The generated examples catalog pairs shared input data with the exact options, commands, and output for every supported scenario. The same definitions drive the catalog, runnable examples, and benchmarks.

Use target, mode, and data to select the output package, API, and scenario. This command runs the simple text Table example:

make example target=text mode=table data=simple

Omit data to run every scenario for the selected package and mode. With no data selected, omit mode to run both APIs, or run make example without arguments to run every available example.

Table library comparison

The following tables compare the public APIs in the versions pinned by the benchmark module.

Formats

This table records the output implementations documented by each library. means the library provides a dedicated output mode for the format, and - means it does not. table targets the GFM table extension; the other Markdown entries indicate generic Markdown table output.

Output formattablego-pretty v6.8.3tablewriter v1.1.4simpletable v1.0.0
Text
HTML-
Markdown
Backlog notation---
CSV or TSV--
SVG---

Features

This table records whether each library exposes a direct public API for a capability in at least one output implementation. It does not imply that every format can express the capability.

Featuretablego-pretty v6.8.3tablewriter v1.1.4simpletable v1.0.0
Streaming API✓ (All)--
Header
Footer
Placeholder✓ (HTML)--
Index column--
Vertical merge-
Horizontal merge
Caller-defined row adapter--
Reflection-based struct input---
CSV input---
Per-column transformation-
Built-in sorting and filtering---
Pagination---
Column hiding--
Width, wrapping, and truncation-
Automatic terminal fit---
Title or caption-
Pluggable output implementation---

For table, the feature matrix has the following qualifications:

  • Footer callbacks derive values such as totals and averages from captured state.
  • Column hiding is intentionally left to input adaptation, so TableOf and StreamOf can omit fields before rows reach the output package.
  • Merge behavior depends on the selected output format and is documented in the Public API guide.

The go-pretty placeholder entry refers to its HTML EmptyColumn setting.

Performance

[!NOTE] table is designed to minimize allocations and reuses internal buffers via sync.Pool. In steady-state benchmarks, common workloads reach one allocation per render; cold runs require additional allocations to initialize pooled state.

Run make bench target=comparison benchtime=1x count=1 to reduce steady-state amortization and expose one-iteration setup costs. For explicit pool-drained measurements of table, run make bench target=cold.

Run the comparison on your machine with make bench target=comparison. The following output records all five samples on an Apple M2 with Go 1.27.0:

$ make bench target=comparison
go test -benchmem -count 5 -benchtime 10000x -cpuprofile cpu.prof -memprofile mem.prof . -bench '^BenchmarkComparison'
goos: darwin
goarch: arm64
pkg: benchmarks
cpu: Apple M2
BenchmarkComparisonTableSimple-8           10000        2436 ns/op       225 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1847 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1739 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1804 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonTableSimple-8           10000        1773 ns/op       224 B/op         1 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       10580 ns/op      8155 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       10572 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       11115 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       11826 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonGoPrettySimple-8        10000       10688 ns/op      8153 B/op       110 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       81974 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       79278 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       81598 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       87737 ns/op    486949 B/op       973 allocs/op
BenchmarkComparisonTableWriterSimple-8     10000       80748 ns/op    486948 B/op       973 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       23490 ns/op     13109 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       23955 ns/op     13098 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       22876 ns/op     13121 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       22583 ns/op     13116 B/op       425 allocs/op
BenchmarkComparisonSimpleTableSimple-8     10000       22650 ns/op     13098 B/op       425 allocs/op
BenchmarkComparisonTableComplex-8          10000        9192 ns/op      1150 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9158 ns/op      1150 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9176 ns/op      1149 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9128 ns/op      1149 B/op        35 allocs/op
BenchmarkComparisonTableComplex-8          10000        9106 ns/op      1150 B/op        35 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       63998 ns/op     49260 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       63791 ns/op     49260 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       61935 ns/op     49263 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       64352 ns/op     49261 B/op       317 allocs/op
BenchmarkComparisonGoPrettyComplex-8       10000       62202 ns/op     49261 B/op       317 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      276792 ns/op    720005 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      280501 ns/op    719999 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      277848 ns/op    720000 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      278027 ns/op    719994 B/op      4749 allocs/op
BenchmarkComparisonTableWriterComplex-8    10000      279195 ns/op    719997 B/op      4749 allocs/op
PASS
ok      benchmarks      24.222s

The table summarizes those five samples. Each cell shows allocs/op · ns/op; both values are medians.

Scenariotablego-prettytablewritersimpletable
Simple1 · 1,804110 · 10,688973 · 81,598425 · 22,876
Complex values35 · 9,158317 · 63,7914,749 · 278,027-

- indicates that a library cannot express the scenario with the benchmark input.

The comparison benchmark uses the shared Simple and Complex data sets. Static data is converted to each library's required row type before timing begins. Each timed iteration constructs a table, processes the rows, and writes the result to a reused buffer. Complex compares native value handling rather than equivalent rendered bytes.

The benchmark preserves each library's configuration model: table uses only functional options, go-pretty accumulates settings through setters, tablewriter combines constructor options with methods, and simpletable receives prebuilt cells through exposed table sections. These native construction paths remain inside each timed iteration. Only the settings needed to align table structure and preserve header text are applied; border characters and value formatting retain each library's defaults.

Documentation

Use these references to select the API, understand its design, and work on the module itself.

ResourceContents
Go ReferenceExact declarations and symbol documentation
Public API guideOptions, output behavior, defaults, and format capabilities
ArchitecturePackage structure, data flow, and state ownership
Design specificationDesign decisions, invariants, tradeoffs, and non-goals
Development guideTest, benchmark, coverage, and analysis commands
Performance baselineBenchmark procedure and performance acceptance criteria

Author

nekrassov01

License

MIT

Contributors

Languages

Go

99.7%