Skip to the tool
DevToolBench

Markdown Table Generator

Grid or pasted CSV into an aligned GFM table.

The first row is the header. Every Markdown table needs one.

Rows
2
Columns
3
Characters
79
Padding
On

Everything runs in your browser. Nothing you type is sent to a server.

Found a bug in this tool? Report it.

Share this tool

What the generator does

This Markdown table generator turns an editable grid, or a block of CSV or TSV pasted straight out of a spreadsheet, into a GitHub Flavored Markdown table. You choose the alignment of each column, the pipes are padded so the raw text stays readable, bars inside a cell are escaped, and line breaks become <br> because Markdown has no multi-line cell.

Everything happens in the page. Nothing is uploaded, which matters when the table you are pasting came out of an internal report.

Tables are GFM, not CommonMark

This surprises people, and it explains most of the times a table renders as a wall of pipes. The CommonMark specification has no table syntax at all. Tables arrived through GitHub Flavored Markdown and were adopted from there by nearly everything, but adoption is not the same as the core standard.

In practice that means tables work in GitHub, GitLab, Bitbucket, Obsidian, Docusaurus, MkDocs, Hugo, Jekyll, VS Code preview and Discourse, and fail in anything running a plain CommonMark parser with no extensions. If a table has to survive an unknown renderer, an HTML table is the only safe answer.

The delimiter row is the whole grammar

A Markdown table is three parts: a header row, a delimiter row and any number of body rows. The delimiter row is the one that carries meaning beyond decoration.

--- sets no alignment and lets the renderer decide, which in every renderer worth naming means left. :--- forces left, ---: forces right and :---: centres. There is no way to align a single cell, only a whole column, and there is no vertical alignment at all.

The header row is not optional either. Because the delimiter row must sit directly under it, a table cannot begin with data, and there is no headerless variant. If your data genuinely has no header, the honest options are a first row of empty cells or a list instead of a table.

Padding, and why the compact toggle exists

Both of these render identically:

| Name         | Since |
| :----------- | ----: |
| Ada Lovelace |  1843 |
| Name | Since |
| :--- | ---: |
| Ada Lovelace | 1843 |

The padded version is far easier to read and edit in the raw file, which is the whole point in a README or a design document that people open in an editor. The compact version wins when the table is generated by a script on every build: with padding, changing one value can widen a column and rewrite every line of the table, so a one-word change shows up in review as a twenty-line diff.

Pick padded for documents that humans maintain and compact for anything a machine regenerates.

When a table is the wrong shape

A Markdown table is a grid of short strings and nothing else. If the cells contain paragraphs, code blocks, lists or images, the syntax will technically hold but the result is unreadable on a phone, where a wide table either scrolls sideways or squashes to nothing.

Three columns is comfortable, five is the practical limit for prose documentation, and beyond that a definition list or a set of subheadings usually communicates better. Long free-text notes belong under the table, not inside it.

If the data started life as a spreadsheet export, the CSV to JSON converter is the better destination when the target is code rather than a document, and JSON to CSV covers the trip back. To put the rows in a sensible order before you paste them here, sort lines does it without a spreadsheet.

Frequently asked questions

Why does my table render as plain text on some sites?

Because tables are not part of CommonMark. They come from the GitHub Flavored Markdown specification, and a renderer only understands them if it has the tables extension switched on. GitHub, GitLab, Bitbucket, Obsidian, Notion and most static site generators do. A bare CommonMark renderer, some comment boxes and a few older wikis do not, and there the pipes appear exactly as you typed them. The fix is an HTML table, or a different way of showing the data.

What is the second line of dashes for?

It is the delimiter row, and it is compulsory. It tells the parser how many columns the table has and how each one is aligned. A colon on the left means left, a colon on both ends means centre, a colon on the right means right, and no colon at all leaves the decision to the renderer, which almost always means left. A table missing that row is not a table to the parser, which is why the first row can never be data.

Can a cell contain more than one line?

No. A row is a line, and the moment you press return you have ended the row. Anything pasted with a line break inside it is joined here with a br tag, which is what every real-world Markdown table does, and it renders as a line break on GitHub. If you need paragraphs, lists or a code block inside a cell, you have outgrown the syntax and should write an HTML table instead.

Do the pipes have to line up in the source?

Not at all. The padding is purely for the human reading the raw file, and the rendered output is identical either way. Padding is worth having in a README that people open in an editor, and worth losing in a file that is generated on every build, because a one-character edit reflows the whole column and the diff turns into noise. That is what the compact toggle decides.

How do I put a pipe character inside a cell?

Escape it as a backslash followed by a pipe, which this page does for you as you type. An unescaped pipe ends the cell early, so a row with a regular expression or a shell command in it will quietly gain a column and push everything after it out of place. Escaping is also why a table is a poor container for code snippets in the first place.

Related tools

Updated