tablemark

Turn arrays of JSON objects into clean, configurable GitHub-flavored markdown tables.

Library
npm
v4.1.0
99stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
37/100Needs Attention
Development Activity16
Maintenance20
Community40
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture85
Code Quality90
Innovation78
Learning Curve80

tablemark converts arrays of JavaScript objects into GitHub-flavored markdown tables, handling column alignment, header casing, and text wrapping so generated docs and README examples come out consistently formatted. It exposes a single tablemark() function that infers columns and headers from the first object’s keys, then lets callers override almost every aspect of the render — per-column alignment and width, custom cell and header title transforms, and strategies for what happens when content overflows or contains line breaks.

Under the hood it accounts for real-world text: it detects ANSI escape codes and wide/CJK/emoji characters so tables stay visually aligned even when cell content isn’t plain ASCII, with wrap-ansi and string-width doing the heavy lifting. It’s TypeScript-first, ships full type definitions, and is commonly used to auto-generate tables in READMEs, CLI output, and docs pipelines.

What You Get

  • A single tablemark(input, options) function with sensible defaults and no required configuration
  • Per-column overrides for alignment, width, and overflow behavior via the columns option
  • Thirteen header-casing strategies (sentence, camel, kebab, constant, etc.) powered by change-case
  • ANSI escape code and wide-character (CJK/emoji) aware width calculation for visually correct alignment
  • Configurable overflow handling (wrap, truncate start, truncate end) for both header and body cells
  • Full TypeScript type definitions and a fully typed, documented options interface

Common Use Cases

  • Auto-generating option/API reference tables in project READMEs from a source-of-truth data array
  • Formatting JSON API responses or database query results as markdown tables for docs or wikis
  • Rendering aligned markdown tables from CLI or build-tool output, including colored terminal text
  • Producing changelog, report, or comparison tables as part of a documentation-generation pipeline

Under The Hood

Architecture The library is a small, single-purpose pipeline built around one entry point, tablemark() in src/index.ts, which validates the input is iterable, short-circuits on an empty array, normalizes the options object via normalizeOptions (src/utilities.ts) into a fully-resolved internal shape, and hands off to buildMarkdown (src/markdown.ts). buildMarkdown first calls getDataProfile (src/data.ts) to compute a DataProfile — per-column keys, casing-transformed titles, alignments, and content-aware widths (via getMaxStringWidth, which accounts for ANSI/CJK width) — then renders the header and each row through getHeader/getRows/getObjectRow/getRow, which apply the configured wrap method and padding logic to lay out wrapped or truncated cells. A small, self-contained transformAnsiString helper handles header-casing without corrupting embedded ANSI codes. There’s no plugin system or persistent state; the one place a change would ripple widely is the normalized options type in types.ts, since the data profiling and rendering modules both key off its exact shape.

Tech Stack Written in TypeScript as an ESM-only package (Node >=20) with a narrow runtime dependency set: change-case for header text casing, string-width plus wrap-ansi and ansi-regex for terminal-aware string width and wrapping, and wordwrapjs for the simpler “basic” wrap strategy. It’s built with tsdown into a single ESM bundle with generated declaration files, tested with vitest, linted with both oxlint and ESLint under a shared @haltcase/style config, gated by lefthook git hooks and commitlint, and released automatically via semantic-release through GitHub Actions. Type correctness is additionally checked with @arethetypeswrong/core and the experimental tsgo/@typescript/native-preview compiler.

Code Quality The test suite covers basic usage, per-column overrides, header casing, and a large-input stress case, plus a dedicated regression test for a previously filed GitHub issue, all backed by an extensive set of golden markdown snapshot fixtures that pin exact rendered output for dozens of option combinations. Source code is fully typed with explicit RangeError/TypeError throws for invalid options or input rather than silent failures, consistent naming conventions, and JSDoc comments documenting every public option and function. Linting runs through both oxlint and ESLint, and CI executes the suite on every change via a GitHub Actions workflow.

API Design The public surface is intentionally narrow — one function, sensible defaults for every option, and progressive disclosure where root-level settings like alignment and overflow strategy can be overridden per column. Naming is consistent and self-documenting, deprecated options are kept working through an explicit migration shim rather than being hard-removed, and the README documents every option in a table alongside runnable before/after examples. Getting started requires no setup beyond calling the function with an array of objects; the standout design choice is automatic ANSI/Unicode-aware column-width detection, which most comparable table-generation utilities don’t handle out of the box.

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

Search