tablemark
Turn arrays of JSON objects into clean, configurable GitHub-flavored markdown tables.
Repository Health
Technical Analysis
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
columnsoption - 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.