β Blog Β· May 23, 2026 Β· dev, markdown
Markdown Tables: When to Hand-Write vs Use a Generator
Hand-write a Markdown table if it has under 4 columns and under 8 rows β anything bigger and you waste more time aligning pipes than writing content. The threshold is when the widest cell in column N changes and you have to re-pad every other row to match. Generators do this in milliseconds. Humans do it in minutes.
The minimal syntax
A Markdown table is two lines minimum: a header row and a separator row. Both use the| character as a column delimiter. The separator row uses - and optional : for alignment.
| Name | Role | Years | | ----- | -------- | -----:| | Alice | Engineer | 7 | | Bob | Designer | 3 |
Renders as a 3-column table with the last column right-aligned (note the : on the right). The leading and trailing | on each row are optional in GitHub Flavored Markdown but required for portability β write them.
Alignment, in 4 characters
| Separator | Alignment |
|---|---|
--- | Default (left in most renderers) |
:--- | Left |
:---: | Center |
---: | Right |
That is the entire alignment spec. There is no justify, no per-cell alignment, no vertical alignment. If you need more, you are not writing Markdown β you are writing HTML.
Hand-writing is fine when the table is small
Three columns, five rows. You can eyeball it. You don't need a tool. The cost of opening a generator exceeds the cost of typing the pipes. Most engineering documentation tables fall in this range β release notes, API parameter lists, decision tables.
| Method | Path | Auth | | ------ | -------------- | ---- | | GET | /users | Yes | | POST | /users | Yes | | GET | /users/:id | Yes | | DELETE | /users/:id | Admin|
Twenty seconds to type. Aligned by eye. Done. Don't pull out a generator for this.
Generators win past these thresholds
- 5+ columns. Column widths interact unpredictably; re-padding cascades.
- 10+ rows. Any cell width change forces a global re-align.
- Data already exists in CSV, JSON, or a spreadsheet. Conversion is a one-shot task.
- Cells contain Markdown (links, inline code). Counting display width manually is error-prone.
- You will edit the table again. The second edit costs as much as the first if you hand-aligned.
Paste CSV or hand-write rows in our Markdown table generatorβ it auto-pads, supports per-column alignment, and outputs portable GFM syntax.
The portability matrix
| Renderer | Tables supported? | Alignment? |
|---|---|---|
| GitHub Flavored Markdown | Yes | Yes |
| GitLab | Yes | Yes |
| CommonMark (strict) | No β tables are an extension | β |
| Pandoc (default) | Yes (4 table syntaxes!) | Yes |
| Notion | Imports as a database, not a table | N/A |
| Discord | No | No |
Strict CommonMark does not include tables. Every renderer that supports them does so as an extension. The most universal subset is GitHub Flavored Markdown (GFM) β write tables for GFM and they work on GitHub, GitLab, Bitbucket, most static site generators, and most wikis.
Five gotchas that bite hand-writers
- Pipes inside cells. A literal
|ends a cell. Escape it as\|or wrap the cell in backticks:`a|b`. - Newlines inside cells. Not allowed in Markdown tables. Use
<br>for a visual line break β renderers vary on whether they respect it. - Empty cells. Two adjacent pipes (
||) render as an empty cell. Leave a space inside (| |) for readability. - Different column counts per row. The header sets the column count. Excess cells in body rows are dropped silently in GitHub.
- Indented tables. Indent a table 4 spaces and most renderers treat it as a code block. Tables must start at column 0.
Generating from CSV β the 3-line script
// CSV in β Markdown table out
function csvToMd(csv: string): string {
const rows = csv.trim().split('\n').map(r => r.split(','));
const head = '| ' + rows[0].join(' | ') + ' |';
const sep = '| ' + rows[0].map(() => '---').join(' | ') + ' |';
const body = rows.slice(1).map(r => '| ' + r.join(' | ') + ' |').join('\n');
return [head, sep, body].join('\n');
}Skips alignment and width-padding. Renders correctly. Good enough for 90% of cases β for the other 10%, our table generator does width-padded output and per-column alignment.
When to skip Markdown tables entirely
If you need merged cells, nested tables, or rich formatting inside cells β write HTML. Markdown is a plain-text format with a 90% coverage of common cases. The 10% it doesn't cover, it doesn't cover. Don't fight it.
Tools
- Markdown Table Generator β CSV/manual input, auto-padded output
- Markdown Preview β live render to verify syntax
- JSON / CSV Converter β convert API output to table-ready CSV
- Word Count β for fitting a table into a length budget
- Case Converter β normalize header capitalization