CSV to Markdown Table

Paste CSV and get a Markdown table ready for a README, a pull request, a wiki page or Notion. The table is built locally, so internal numbers never leave your machine.

CSV → Markdown

Input

Settings

History

Load from URL

Where Markdown tables are used

Typing a Markdown table by hand is tedious: every row needs pipes, the delimiter row needs dashes, and columns drift out of alignment as soon as a value changes. Generating it from CSV is faster and less error-prone. Typical uses:

  • Benchmark results or a feature matrix in a GitHub README or pull request description.
  • Release notes, runbooks and documentation in GitLab, Confluence-compatible wikis, Obsidian or Docusaurus.
  • Pasting spreadsheet data into a chat or issue tracker that renders Markdown.

The output follows GitHub Flavored Markdown (GFM) table syntax, which nearly every modern Markdown renderer supports.

How the table is built

The CSV is parsed with RFC 4180 rules, so quoted commas and doubled quotes are handled before any Markdown is produced. Then:

  • Every column is padded to the width of its longest value, so the raw Markdown reads as a table too. Width is measured visually, so CJK characters and emoji line up.
  • Columns whose non-empty values are all numeric — 129.90, -12, 1,234.50, 3.5e4, 12% — are right-aligned with a ---: delimiter; text columns stay left-aligned.
  • Rows shorter than the widest row are padded with empty cells, because a GFM table needs the same number of cells in every row.
  • Pipe characters inside values are escaped as \| and backslashes as \\, so they cannot break the table.
  • Line breaks inside quoted cells become <br>, since a Markdown table row must stay on one line.

Values are not reformatted: dates, IDs and decimals appear exactly as in the CSV.

First row is a header

Markdown tables always have a header row. With First row is a header on (the default), the CSV’s first row supplies the column titles. Turn it off when the CSV has no header: the table then gets generic titles Column 1, Column 2 and so on, and every CSV row becomes a body row. Rename the titles afterwards in the generated Markdown.

Limits of Markdown tables

GFM tables cannot merge cells, span rows, or hold block content such as lists or code blocks; cells contain inline text only. Very wide tables will scroll or wrap depending on the renderer, so consider dropping columns you do not need before converting. Inline Markdown inside cells — **bold** or [links](https://example.com) — is passed through untouched and will render.

If you need styling, borders or HTML features, use CSV to HTML table instead. Preview the result with the Markdown formatter, or convert it to HTML with Markdown to HTML. The work is done in your browser either way.

Examples

Benchmark results for a README

The two numeric columns are right-aligned, and the quoted comma in the last note stays inside its cell.

Input
library,ops/sec,p99 (ms),notes
fast-json,1240000,0.8,default build
json-bigint,310000,3.1,keeps 64-bit ints
yaml,95000,12.4,"YAML 1.2, strict"
Output
| library     | ops/sec | p99 (ms) | notes             |
| ----------- | ------: | -------: | ----------------- |
| fast-json   | 1240000 |      0.8 | default build     |
| json-bigint |  310000 |      3.1 | keeps 64-bit ints |
| yaml        |   95000 |     12.4 | YAML 1.2, strict  |
Open this example in the tool

Cells with pipes and line breaks

The pipe in the command is escaped so it does not split the cell, and the two-line description is joined with <br>.

Input
command,description
ls | wc -l,"Counts files
in the current directory"
grep -c,Counts matching lines
Output
| command     | description                              |
| ----------- | ---------------------------------------- |
| ls \| wc -l | Counts files<br>in the current directory |
| grep -c     | Counts matching lines                    |
Open this example in the tool

CSV without a header

Generic Column 1 to Column 3 titles are added and all three rows appear in the table body.

Input
JSON,MVP,shipped
YAML,MVP,shipped
TOML,v2,planned
Output
| Column 1 | Column 2 | Column 3 |
| -------- | -------- | -------- |
| JSON     | MVP      | shipped  |
| YAML     | MVP      | shipped  |
| TOML     | v2       | planned  |
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
This quoted field is never closed
Explained
A CSV field opens a quote that never closes, so the rest of the input would be one cell.Close the quote, doubling any quotes that belong inside the value.
Row has 2 fields, expected 4; the missing fields are left empty
Explained
A warning: a row is shorter than the header. The table pads it with empty cells.Check for missing commas in that row if the empty cells are unexpected.
Table renders as plain text with pipesThe Markdown renderer does not support GFM tables, or the table was pasted without a blank line before it.Leave an empty line above the table, and confirm the platform supports GitHub Flavored Markdown.

Frequently asked questions

Why are some columns right-aligned?

Columns where every non-empty value looks like a number get a —: delimiter so digits line up, which is easier to compare.

Can a Markdown table cell contain a line break?

Not literally, so line breaks are converted to <br>, which GitHub and most renderers display as a new line.

What if my data contains the | character?

It is escaped as | so the renderer shows a pipe instead of starting a new column.

Does this work for GitHub, GitLab and Notion?

Yes. They all accept the GFM table syntax produced here. Notion converts it to a native table when pasted.

Related tools