markdown-table
Turns arrays of strings into aligned GitHub-flavored markdown tables with configurable padding and column alignment.
Repository Health
Technical Analysis
markdown-table is a lightweight, dependency-free JavaScript utility from unified/remark ecosystem author Titus Wormer that converts a two-dimensional array of strings into a properly formatted GitHub Flavored Markdown (GFM) table. It handles column alignment (left, right, or center), delimiter padding, and serialization of primitives like numbers, booleans, null, and undefined, so callers don’t have to hand-roll ASCII table formatting logic themselves.
Unlike a full markdown processor, it doesn’t parse or escape content — it’s intentionally scoped to just the table-generation step, making it a natural building block for CLI tools, documentation generators, changelog scripts, and reporting tools that need to emit readable markdown output. For projects that need a complete markdown AST pipeline, the author recommends pairing mdast-util-to-markdown with mdast-util-gfm instead.
What You Get
- A single
markdownTable(table, options)function with zero runtime dependencies - Per-column left/center/right alignment via a simple ‘l’/‘c’/‘r’ string or array
- Automatic delimiter-column alignment so table source reads cleanly, with an option to disable it for staggered output
- A custom
stringLengthhook for correctly aligning columns containing full-width characters or emoji - Full TypeScript type definitions generated from JSDoc, including the exported
Optionstype
Common Use Cases
- Generating changelog or release-note tables from git/CI data in a build script
- Rendering tabular query results as markdown inside a CLI tool or chat bot
- Building documentation generators that emit GFM tables from structured data (API references, config option tables)
- Formatting comparison or benchmark output in a README or PR comment
Under The Hood
Architecture
The package is a single-file, single-function library (index.js, ~394 lines including heavy JSDoc): one exported markdownTable(table, options) runs three sequential passes over the input — building a cell/size matrix per row, computing a per-column alignment code, splicing in a synthesized alignment-delimiter row, then a final render loop that assembles each output line while respecting padding, delimiter-start/end, and alignDelimiters settings — backed by two small private helpers (serialize for value coercion, toAlignment for mapping align characters to codes). There is no I/O, no async, no class hierarchy, and no external dependency; the design deliberately returns a plain string rather than an AST, so the only real breaking-change surface is the documented Options shape.
Tech Stack
Pure vanilla JavaScript targeting ES2020/Node 14.14+ and 16+, published ESM-only ("type": "module") with zero runtime dependencies. Types come from JSDoc compiled via TypeScript’s checkJs/emitDeclarationOnly into .d.ts/.d.ts.map files — no bundler or build framework, the shipped artifact is the raw index.js plus generated declarations. Dev tooling includes xo (an ESLint preset) and prettier for linting/formatting, remark-cli with remark-preset-wooorm for linting the README itself, c8 for coverage and type-coverage for strict type-coverage enforcement, and Node’s built-in node:test runner with node:assert/strict for tests. CI is a single GitHub Actions workflow matrix-testing the current and an older LTS Node release, uploading coverage to Codecov.
Code Quality
The test suite (test.js, 337 lines) uses the native Node test runner to exercise the full public API, every alignment/padding/delimiter option, primitive serialization edge cases (numbers, booleans, null, undefined, arrays), and irregular row lengths. Both c8 --check-coverage (100% line coverage) and type-coverage (100% strict type coverage) are hard CI gates rather than aspirational targets. Error handling is minimal because the function has few failure modes, favoring defensive defaults (settings.align || [], a defaultStringLength fallback) over thrown exceptions. Naming and formatting are enforced consistently through the xo/prettier config embedded in package.json, and the whole module is strictly typed with exactOptionalPropertyTypes enabled.
API Design
The public surface is intentionally tiny: one function, one options object, no classes or builder pattern to learn. Defaults favor the common case (left-aligned, padded, delimiter-wrapped tables) while every formatting toggle (align, padding, delimiterStart, delimiterEnd, alignDelimiters, stringLength) is opt-in and independently documented with before/after markdown examples in the README, which keeps the getting-started boilerplate to a single import and function call.
Used by 3 apps in this directory
LobeHub
AI Assistants · Productivity · Automation
Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.
Plausible Analytics
Analytics
Open-source, cookie-free web analytics that respects visitor privacy and replaces Google Analytics.
Supabase
Developer Tools · Databases · Search
The open-source Postgres development platform that replaces Firebase with authentication, real-time APIs, edge functions, storage, and vector embeddings — all built on PostgreSQL.