table
Renders arrays of data as clean, precisely aligned ASCII/Unicode tables for terminal output, with full ANSI-color and fullwidth-character awareness.
Repository Health
Technical Analysis
table is a TypeScript library that turns two-dimensional arrays of arbitrary data into readable, borderable text tables for terminal or log output. It handles the parts that are easy to get wrong when hand-rolling this yourself: measuring true display width for fullwidth (CJK) characters and ANSI-colored strings (so a chalk-colored cell doesn’t blow out the column width), wrapping long content at word boundaries or a fixed character count, aligning and vertically centering cell contents, and drawing configurable borders including merged spanning cells across rows and columns.
Beyond the one-shot table() function, it exposes a createStream() API for incrementally appending rows to a live-updating table in place — useful for progress displays or tailing output — and a getBorderCharacters() helper for picking from built-in border styles (honeywell, norc, ramac, void) or supplying your own. Configuration is validated against a JSON Schema compiled ahead-of-time with ajv, so malformed config throws a clear, specific error rather than failing silently deep in the rendering pipeline.
What You Get
- A
table(data, config)function that renders anyunknown[][]as an aligned, bordered text table in one call - A
createStream(config)API for writing rows incrementally to a live, in-place-updating terminal table getBorderCharacters(name)presets (honeywell, norc, ramac, void) plus fully custom border character sets- Column-level configuration: width, alignment, vertical alignment, padding, truncation, and word-wrapping
- Spanning-cell support to merge content across multiple rows and/or columns in a single table
- ANSI-escape-aware and fullwidth-character-aware width calculation so colored or CJK content still aligns correctly
- Ahead-of-time JSON-Schema config validation (via ajv) that throws descriptive errors for invalid configuration
Common Use Cases
- CLI output formatting - printing structured results (lists of records, diffs, comparisons) as readable tables in command-line tools
- Test and build reporters - rendering pass/fail summaries, coverage tables, or benchmark results in terminal test runners
- Log and debug output - dumping arrays of objects as scannable tables during local development or CI logs
- Live progress displays - using
createStream()to show rows appended in real time (e.g. per-file processing status) without re-rendering the whole table - Data comparison tables - laying out before/after or multi-column comparisons with merged header cells via spanning-cell config
Under The Hood
Architecture table.ts orchestrates a linear, purely-functional pipeline: validateTableData -> stringifyTableData -> injectHeaderConfig -> makeTableConfig -> truncateTableData -> calculateRowHeights -> spanningCellManager row-height/index mapping -> mapDataUsingRowHeights -> alignTableData -> padTableData -> calculateOutputColumnWidths -> drawTable, with each stage a small, single-purpose module that transforms the same immutable rows array and a shared config object built by makeTableConfig from an ajv-validated JSON Schema. createStream.ts reuses the same compute-layer functions (stringifyTableData, alignTableData, padTableData, drawRow/drawBorder) for a stateful incremental writer, keeping process.stdout.write side effects confined to a thin imperative shell around the pure core. The one genuinely stateful abstraction is spanningCellManager, which calculateRowHeights, mapDataUsingRowHeights, alignSpanningCell, and drawTable all consult for merged-cell queries — it’s the piece that would ripple outward if the spanning-cell model changed.
Tech Stack
Written in strict-mode TypeScript (ES2018 target, CommonJS output, noUnusedLocals/noImplicitReturns enabled) with no runtime framework dependency. Configuration correctness is delegated to ajv: JSON Schemas under src/schemas/ (config.json, streamConfig.json, shared.json) are compiled ahead-of-time via ajv compile into a standalone src/generated/validators.js, avoiding runtime schema-compile cost in consumers. Display-width correctness comes from string-width (fullwidth/CJK-aware) and slice-ansi/strip-ansi (ANSI-safe truncation and measurement), with lodash.truncate for plain text truncation. The package ships plain tsc output (dist/src) referenced by both main and module in package.json rather than a bundled build.
Code Quality
The test/ directory mirrors src/ nearly 1:1 (48 test files for ~35 src modules), using mocha, chai, and sinon, with nyc (Istanbul) enforcing a 95%-line-coverage gate as part of npm test. Error handling is explicit rather than swallowed: validateTableData throws typed errors with specific messages for non-array input, inconsistent column counts, and embedded control characters, and malformed table config is rejected by the ajv-generated validator before rendering begins. ESLint (eslint-config-canonical) and TypeScript strict mode enforce style and type safety, and GitHub Actions CI runs build, lint, and test across Node 10/12/14 on every push and pull request, uploading coverage to Coveralls.
What Makes It Unique
Most terminal-table libraries either ignore ANSI escape codes and fullwidth characters when computing column widths (breaking alignment on colored or CJK content) or hand-roll config validation. table combines string-width- and ANSI-aware width measurement with schema-validated, ahead-of-time-compiled configuration, and adds spanning-cell support for merging content across rows and columns — a feature largely absent from comparable packages. The createStream API additionally allows a table to be built incrementally, redrawing only the trailing border on each write, which suits streaming or tailing use cases that a purely batch table(data) call cannot serve.
Used by 4 apps in this directory
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
Karakeep
Bookmarks Archiving
Self-hosted bookmark manager that captures links, notes, images, and PDFs with AI tagging, full-text search, and automatic archiving.
Kibana
Analytics · Monitoring
Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.
typesense
Search
A blazing-fast, typo-tolerant open-source search engine that delivers instant search experiences with built-in vector, semantic, and geo-search — all from a single binary.