Skip to content

GitHub Markdown Tables: How to Add a Table to a README

By MarkdownTables.com editorial teamUpdated

On this page

How do I add a table to a GitHub README?

  1. Write the header row: | Command | Description | Default |.
  2. Add the delimiter row right under it with one cell per column. Use :--- for left, :---: for center and ---: for right alignment.
  3. Add the data rows, one per line. The pipes don't have to line up.
  4. Leave a blank line before and after the table, then check the Preview tab (in the web editor) before committing.
A typical README table: CLI commands with a right-aligned column
Markdown
| Command         | Description              | Default |
| :-------------- | :----------------------- | ------: |
| `init`          | Create a config file     |       — |
| `build --watch` | Rebuild on file changes  |   false |
| `serve -p`      | Port for the dev server  |    3000 |
Preview
CommandDescriptionDefault
initCreate a config file—
build --watchRebuild on file changesfalse
serve -pPort for the dev server3000

Inline code, links and emoji all work in cells. Right-align numbers so the digits line up.

Open in editor : A typical README table: CLI commands with a right-aligned column

How many hyphens? GitHub Docs say each column of the delimiter row needs at least three hyphens. The underlying GFM spec only requires one, and GitHub renders |-|-| fine. Use three: it matches the docs, reads better, and is what formatters and linters produce. The full rules are in the Markdown table syntax guide.

What works inside a GitHub table cell

A GitHub table cell holds one line of inline content. GitHub also accepts a set of HTML tags inside cells, which covers most of what pipe syntax can't do.

Cell content on GitHub (README, issues, PRs, wikis)
ContentWorks?How to write it
Bold, italic, strikethrough✅ Yes**bold**, *italic*, ~~old~~
Inline code✅ YesBackticks; escape a pipe inside as \|
Links and images✅ Yes[text](url), ![alt](url)
Image size✅ With HTML<img src="…" width="48">
Line break✅ With HTML<br>
Bulleted list✅ With HTML<ul><li>One</li><li>Two</li></ul> on one line
Keyboard keys, sub/superscript✅ With HTML<kbd>, <sub>, <sup>
Collapsible content✅ With HTML<details><summary>More</summary>…</details>
Math✅ Yes$x^2$; write \vert instead of |
Emoji✅ YesUnicode (✅) or shortcodes (:white_check_mark:)
Task checkboxes [x]❌ Literal textUse ✅ / ☐ instead
Text color, style, <font>❌ StrippedUse emoji or badges to signal status
Fenced code block, heading, Markdown list❌ NoSwitch the table to HTML (see below)
Merged cells❌ NoHTML colspan / rowspan
<kbd> keys in a shortcuts table
Markdown
| Action        | Windows / Linux                    | macOS                          |
| :------------ | :--------------------------------- | :----------------------------- |
| Command palette | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> | <kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> |
| Search files  | <kbd>Ctrl</kbd>+<kbd>P</kbd>        | <kbd>Cmd</kbd>+<kbd>P</kbd>     |
Preview
ActionWindows / LinuxmacOS
Command paletteCtrl+Shift+PCmd+Shift+P
Search filesCtrl+PCmd+P

GitHub draws <kbd> as a small key cap. Renderers that strip HTML show the tags as text.

Open in editor : <kbd> keys in a shortcuts table

More detail on each: line breaks and lists in cells, collapsible tables, math in tables and checkboxes and status icons.

Images, badges and avatars in a README table

Images work in cells with normal Markdown. A badge is just an image; wrap it in a link to make it clickable: [![alt](badge-url)](target-url). GitHub serves external images through its own image proxy, so they load for every reader without exposing their IP addresses to the badge host.

shields.io badges in a package table
Markdown
| Package | Version | CI |
| :------ | :-----: | :-: |
| `@acme/core` | [![npm](https://img.shields.io/badge/npm-v3.4.1-blue)](https://www.npmjs.com/) | ![build](https://img.shields.io/badge/build-passing-brightgreen) |
| `@acme/cli` | [![npm](https://img.shields.io/badge/npm-v1.0.0-blue)](https://www.npmjs.com/) | ![build](https://img.shields.io/badge/build-failing-red) |
Preview
PackageVersionCI
@acme/core![npm](https://www.npmjs.com/)build
@acme/cli![npm](https://www.npmjs.com/)build

Markdown image syntax has no size option, and a large image stretches its column. Use an HTML <img> with a width (and optionally height) attribute; GitHub keeps those attributes but removes style, so rounded corners or borders via CSS won't apply.

A sized avatar in a maintainers table
Markdown
| Maintainer | Role | Profile |
| :--------: | :--- | :------ |
| <img src="https://github.com/octocat.png" width="48" alt="octocat"> | Lead | [@octocat](https://github.com/octocat) |
Preview
MaintainerRoleProfile
octocatLead@octocat

Images that switch with dark mode

A dark logo or diagram can disappear on GitHub's dark theme. GitHub supports the HTML <picture> element with a prefers-color-scheme media query, so readers get the right version for their theme. It is multi-line HTML, so use it in an HTML table cell or above the table rather than in a pipe cell. The older #gh-dark-mode-only / #gh-light-mode-only URL suffixes are deprecated in favor of <picture>.

Theme-aware imageHTML
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="docs/arch-dark.png">
  <img src="docs/arch-light.png" alt="Architecture diagram" width="400">
</picture>

For badge layouts, alt text and avatar grids, see images and badges in tables.

Code and code blocks in a GitHub table

Inline code works; fenced code blocks don't. A pipe-table cell has to fit on one line, so a ``` block can't go inside it. Three options, from simplest:

  1. Inline code plus <br> for short multi-line snippets. Escape any pipe as \|, even inside backticks: GFM splits the row into cells before it reads code spans. GitHub removes the backslash, so the code shows a plain |.
  2. An HTML table for real code blocks. Put the fenced block inside a <td> with a blank line before and after it, and GitHub renders it with syntax highlighting.
  3. Move the code out and link to it from the table, which is often the more readable README anyway.
Inline code, <br> and an escaped pipe
Markdown
| Task    | Command                                   |
| :------ | :---------------------------------------- |
| Install | `npm install`                             |
| Build   | `npm run build`<br>`npm run test`         |
| Search  | `grep -E "error\|warn" app.log`          |
Preview
TaskCommand
Installnpm install
Buildnpm run build
npm run test
Searchgrep -E "error|warn" app.log

The \| inside the grep pattern keeps the cell intact. See escaping pipes.

Open in editor : Inline code, <br> and an escaped pipe
A fenced code block inside an HTML table cellHTML
<table>
<tr><th>Language</th><th>Example</th></tr>
<tr>
<td>JavaScript</td>
<td>

```js
const total = items.reduce((sum, i) => sum + i.price, 0);
```

</td>
</tr>
</table>

If you searched for the opposite, showing a Markdown table as source code in a README, put it in a fenced block with the markdown language tag. Inside the fence nothing is rendered, so readers see the pipes:

Displaying table source in a READMEMarkdown
```markdown
| Name | Role     |
| ---- | -------- |
| Ada  | Engineer |
```

How do I center a table in a README?

Markdown has no centering syntax, and GitHub strips style attributes, so margin: auto won't work. The legacy HTML align attribute is kept: wrap the table in <div align="center">. The blank lines inside the div matter; without them GitHub treats the table as part of the HTML block and shows the raw pipes.

Centering a table in a README
Markdown
<div align="center">

| Plan | Price |
| :--- | ----: |
| Free |    $0 |
| Pro  |   $12 |

</div>

The preview here shows the table only; on GitHub it sits in the middle of the page. For an HTML table, <table align="center"> does the same.

Centering a column's contents is a different thing: use :---: in the delimiter row. See column alignment.

Wide tables, column width and long content

When a table is wider than the content area, GitHub keeps the columns intact and adds a horizontal scrollbar to the table instead of squeezing it. That is fine for reference tables, but readers on phones see only the first columns. Ways to keep wide tables usable:

  • Cut or merge columns. A handful of short columns fits a README without scrolling; ten rarely does.
  • Transpose a table with many columns and few rows so it reads top to bottom (the transpose tool swaps rows and columns).
  • Shorten cells with <br> or a link to a details section.
  • Hide long tables in a <details> block so the README stays scannable.
  • Stop a column from wrapping by joining words with &nbsp;; widen one by padding its header the same way. There is no width syntax. See column width.

Can GitHub tables be sortable?

No. GitHub renders Markdown to static HTML and removes JavaScript, so a README table can't be sorted or filtered by clicking its headers. Practical alternatives:

  • Sort the source. Commit the rows in the order readers need (alphabetical, by version, by date). The Markdown table sorter sorts by any column, numerically or alphabetically.
  • Publish the data elsewhere. A GitHub Pages site can load a JavaScript table library, and a CSV file in the repository is shown by GitHub as a searchable table.
  • Use GitLab if you control the platform: GitLab's json:table code blocks render tables with sortable columns and an optional filter box. See the GitLab tables guide.

Where GitHub renders tables (and GitHub Pages)

Everything on github.com that accepts Markdown uses the same GitHub Flavored Markdown renderer, so a table that works in a README works in an issue. GitHub Pages is the exception.

Table support across GitHub
Where on GitHubPipe tablesHTML in cells
README and other .md files in a repoRendered with GitHub Flavored Markdown on the file view and repo home page.YesYes: Allowlisted tags; style stripped
Issues, pull requests and commentsSame renderer as files. The editor has a Preview tab.YesYes: Allowlisted tags
DiscussionsYesYes: Allowlisted tags
WikisMarkdown wiki pages; wikis also accept other markup formats with their own table syntax.YesYes: Allowlisted tags
GistsMarkdown files (.md) are rendered; a .txt file shows the raw text.Yes: .md filesYes: .md files
GitHub Pages (Jekyll)Converted by kramdown, not by GitHub’s Markdown renderer. Styling comes from the site theme.Partly: kramdown rules: blank line before, rows start with |Yes: Passed through to the page

✅ supported · ⚠️ partly or with a workaround · ❌ not supported · Last verified October 2026

“Allowlisted tags” means GitHub keeps tags such as <br>, <img>, <kbd>, <sub>, <sup> and <details> but removes style, <font>, scripts and event handlers.

GitHub Pages uses kramdown

A Jekyll site on GitHub Pages converts Markdown with kramdown, not with GitHub's own renderer. Pipe tables still work, but follow kramdown's rules: start each row with a |, leave a blank line before the table, and remember that the table's look (borders, striping) comes from your Jekyll theme's CSS. kramdown also adds extras GFM doesn't have, such as footer rows and tables without a header. If Pages output looks wrong but the README is fine, see GitHub Pages in the troubleshooting guide.

Copyable README table templates

Three table shapes that cover most READMEs. Open any of them in the editor to adapt the columns.

Feature comparison
Markdown
| Feature          | Free | Team | Enterprise |
| :--------------- | :--: | :--: | :--------: |
| Unlimited tables |  ✅  |  ✅  |     ✅     |
| Shared workspace |  ❌  |  ✅  |     ✅     |
| SSO              |  ❌  |  ❌  |     ✅     |
| Support          | Community | Email | Dedicated |
Preview
FeatureFreeTeamEnterprise
Unlimited tables✅✅✅
Shared workspace❌✅✅
SSO❌❌✅
SupportCommunityEmailDedicated

Pair icons with words where meaning matters; screen readers read emoji by name.

Open in editor : Feature comparison
API or config parameters
Markdown
| Parameter | Type      | Required | Default     | Description                        |
| :-------- | :-------- | :------: | :---------- | :--------------------------------- |
| `limit`   | `integer` | No       | `25`        | Records per page (max `100`)       |
| `sort`    | `string`  | No       | `"created"` | `"created"` or `"updated"`         |
| `api_key` | `string`  | Yes      | —           | Project API key                    |
Preview
ParameterTypeRequiredDefaultDescription
limitintegerNo25Records per page (max 100)
sortstringNo"created""created" or "updated"
api_keystringYes—Project API key

Code spans make names and values scannable. Keep descriptions short and link to details.

Open in editor : API or config parameters
Version support matrix
Markdown
| Version | Node.js | Supported          |
| :------ | :------ | :----------------- |
| 4.x     | ≥ 20    | ✅ Active          |
| 3.x     | ≥ 18    | ⚠️ Security fixes  |
| 2.x     | ≥ 14    | ❌ End of life     |
Preview
VersionNode.jsSupported
4.x≥ 20✅ Active
3.x≥ 18⚠️ Security fixes
2.x≥ 14❌ End of life

More starting points are in the table templates, including changelogs, roadmaps and contributor lists.

Common GitHub table mistakes

The delimiter row has the wrong number of cells

The header and delimiter rows must have the same cell count, or GitHub renders the lines as a paragraph with visible pipes. Data rows are more forgiving: missing cells render empty and extra cells are dropped.

Broken: three headers, two delimiter cells
Markdown
| Name | Role | Team |
| ---- | ---- |
| Ada  | Engineer | Platform |
Preview

GitHub shows this as plain text:

| Name | Role | Team | | ---- | ---- | | Ada | Engineer | Platform |

Fixed: one delimiter cell per header
Markdown
| Name | Role     | Team     |
| ---- | -------- | -------- |
| Ada  | Engineer | Platform |
Preview
NameRoleTeam
AdaEngineerPlatform

No blank line inside an HTML wrapper

Inside <div>, <details> or <p>, GitHub only parses Markdown that is separated from the tags by blank lines.

Broken: table pressed against the <div> tags
Markdown
<div align="center">
| Plan | Price |
| ---- | ----: |
| Pro  |   $12 |
</div>
Preview

GitHub shows the raw pipes:

| Plan | Price | | ---- | ----: | | Pro | $12 |

Fix: add a blank line after <div align="center"> and before </div>, as in the centering example above.

Task-list checkboxes in cells

[ ] and [x] only turn into checkboxes at the start of a list item, so in a cell they stay as literal brackets. Use characters that render everywhere:

Status column with ✅ and ☐
Markdown
| Task          | Done |
| :------------ | :--: |
| Write tests   |  ✅  |
| Update docs   |  ☐   |
Preview
TaskDone
Write tests✅
Update docs☐

Other things that catch people out

  • Pipes in code, regex or URLs add a column. Escape every literal pipe as \|.
  • Indenting the table by four or more spaces turns it into a code block.
  • Colors don't survive. style, <font> and CSS classes are stripped; use emoji or badges for status.
  • A line of text right under the table becomes another row. End every table with a blank line.

Paste a table into the Markdown table validator to find the line that breaks it.

When to switch to an HTML table

Pipe tables are the right default for READMEs because they stay readable in the source and in diffs. Write the table in HTML instead when you need:

  • merged cells (colspan, rowspan) — see merged cells
  • fenced code blocks, Markdown lists or several paragraphs in a cell
  • a <caption> or row headers
  • a centered table with <table align="center">, or images side by side in a layout grid

GitHub keeps the table structure but still strips style, so HTML doesn't buy you colors or CSS widths. Convert an existing table with Markdown table to HTML.

Frequently asked questions

Can you make a sortable table in GitHub Markdown?

No. GitHub renders Markdown tables as static HTML and removes scripts, so there is no click-to-sort. Sort the rows before you commit (the table sorter does it in the browser), or host the table on GitHub Pages with a JavaScript table library. GitLab is different: its json:table blocks can be sortable.

How do I put a code block inside a GitHub Markdown table?

You can’t put a fenced code block in a pipe-table cell, because a cell must stay on one line. Use inline code with <br> between lines, or write the table in HTML and put the fenced block inside a <td> with a blank line before and after it.

How do I center a table in a GitHub README?

Wrap it in <div align="center">, leave a blank line after the opening tag and before </div>, and keep the Markdown table between them. GitHub strips style attributes, so CSS such as margin: auto does not work.

How many hyphens does a GitHub table delimiter row need?

One per cell is enough for the GFM spec, so |-|-| renders on GitHub. GitHub Docs say to use at least three hyphens (---), which is the common convention and what other tools expect, so three is the safe choice.

Why does my table show pipes instead of rendering on GitHub?

Usually the delimiter row is missing or has a different number of cells than the header, the table is indented four or more spaces, or it sits inside an HTML tag without blank lines around it. The troubleshooting guide walks through each cause.

Can I set column widths in a GitHub table?

Not with Markdown: column widths follow the content, and GitHub strips style attributes, so CSS widths don’t apply. Pad a header with &nbsp;, or add a transparent spacer image with a width attribute. See column width.

Do checkboxes work in GitHub table cells?

No. [ ] and [x] only become task-list checkboxes at the start of a list item, so inside a cell they show as literal text. Use emoji such as ✅ and ☐ instead. See checkboxes in tables.

Do README tables render on GitHub Pages?

Yes, but Jekyll converts them with kramdown, not with GitHub’s Markdown renderer. Start every row with a pipe, leave a blank line before the table, and expect the look to come from your theme’s CSS.

Build the README table in a grid

Type or paste your data, set alignment per column, and copy GitHub-ready Markdown.

Open the table generator