HTML to Markdown Converter
Convert HTML into Markdown with genuine GitHub-flavour tables, strikethrough and task lists — plus a report of the detail Markdown cannot carry. All processing happens locally in your browser.
Convert HTML into Markdown
Tables, strikethrough and task lists are handled with explicit GitHub-flavour rules, so a table becomes a real Markdown table rather than being left as raw HTML. Anything Markdown cannot express is reported.
# Getting started
Install the CLI with `npm install -g example-cli`, then run:
```bash
example-cli init
example-cli build
```
## Options
- **\--watch** rebuild on change
- **\--verbose** print every step
> Requires Node 18 or later.GitHub extensions are enabled, so the output targets GitHub, GitLab and most static site generators. Turn them off for strict CommonMark.
What is converted, and what Markdown cannot hold
Markdown is a small format on purpose. It covers headings, paragraphs, emphasis, lists, links, images, code and quotes — and stops there. HTML covers all of that plus layout, styling, forms, media, scripting and arbitrary structure.
So converting HTML to Markdown is a deliberate reduction. The question is not whether detail is lost but which detail, and this page reports exactly what it flattened rather than leaving you to discover it later.
| HTML | Markdown |
|---|---|
<h1> to <h6> |
# to ###### |
<strong>, <b> |
**bold** |
<em>, <i> |
_italic_ |
<del>, <s> |
~~struck~~ (GitHub extension) |
<ul>, <ol>, <li> |
- and 1. |
<pre><code> |
Fenced block with the language from class="language-x" |
<table> |
Pipe table (GitHub extension) |
style, class, id |
Nothing — discarded |
<div>, <span> |
Nothing — unwrapped, text kept |
<script>, <iframe>, <svg> |
Removed entirely |
Tables: the extension most converters skip
Turndown, the library underneath this page, implements CommonMark. CommonMark has no table syntax, so by default a <table> is passed straight through as raw HTML. You get a Markdown file with an HTML table inside it.
This page adds explicit GitHub-flavour rules instead. Given:
<table>
<thead>
<tr><th align="left">Feature</th><th align="center">Free</th><th align="right">Price</th></tr>
</thead>
<tbody>
<tr><td>Basic export</td><td>Yes</td><td>0.00</td></tr>
</tbody>
</table>
the output is a real Markdown table, and the align attributes become alignment colons:
| Feature | Free | Price |
| :-- | :-: | --: |
| Basic export | Yes | 0.00 |
Where tables still break down
- Merged cells. Markdown tables are strictly rectangular, so
rowspanandcolspancannot be expressed. The grid is flattened and you are told it happened. - Nested tables. A table inside a table has no Markdown representation at all.
- Block content in a cell. A cell can hold inline formatting but not a list, a paragraph break or a fenced code block. Newlines inside a cell are collapsed to spaces.
- No header row. GFM requires one, so the first body row is promoted to keep the table valid.
- Pipes in content. A literal
|inside a cell is escaped to\|, otherwise it would split the cell.
When a table genuinely needs merged cells, keeping it as HTML is the honest answer — Markdown renderers accept inline HTML, so you can leave that one table alone and convert the rest.
How to convert
- Paste HTML A full page or a fragment. Scripts, iframes, styles and inline SVG are removed before conversion.
- Choose the Markdown style Heading style, bullet marker, code block style, link style and emphasis marker. Different projects have different linting rules for these.
- Enable or disable the GitHub extensions Tables, strikethrough and task lists are on by default. Turn them off for strict CommonMark output.
- Read the flattening report Merged cells, discarded styles, dropped form controls and lost alignment are listed individually.
Examples: the style options in practice
Heading style
ATX: # Getting started
Setext: Getting started
===============
Setext only expresses two levels, because it has just two underline characters. A document with H3 headings therefore ends up mixing both styles, which is why ATX is the usual default and what most Markdown linters expect.
Link style
Inline: See the [upgrade guide](https://example.com/upgrade) for details.
Reference: See the [upgrade guide][1] for details.
[1]: https://example.com/upgrade
Reference style keeps paragraphs readable when URLs are long, and lets one URL be reused. Inline is easier to scan for a short document.
Code blocks
Fenced blocks can carry a language, which indented blocks cannot:
<pre><code class="language-bash">npm install</code></pre>
becomes
```bash
npm install
```
That is a real reason to prefer fenced output: the language tag is what drives syntax highlighting on GitHub and in static site generators.
Cleaning up scraped HTML
Converting a page copied from a website is the most common use of this tool, and the noise follows a predictable pattern:
- Wrapper divs and spans are unwrapped, keeping their text. A page built from nested layout containers usually reduces to about a third of its original size.
- Inline styles and classes are discarded, because Markdown has no styling syntax. Anything conveyed only by CSS — a highlighted callout, a coloured warning — becomes plain text.
- Centred blocks lose their alignment.
<div align="center">has no Markdown equivalent. - Tracking scripts and analytics tags are removed outright rather than being converted to text.
- Relative image paths are preserved exactly as written, so
/diagram.pngstays relative and will need rewriting for its new home. - Non-breaking spaces survive as characters. They look like ordinary spaces but are not, which can be confusing later.
Superscript, subscript and definition lists have no Markdown syntax at all. GitHub-style renderers accept inline HTML, so leaving <sup> in place is usually the right call — but a strict CommonMark renderer with HTML disabled will show it as literal text.
Use cases
- Migrating documentation off a CMS. Export the HTML and convert it into Markdown files for a static site generator or a docs repository.
- Turning a web page into notes. Obsidian, Notion and Bear all read Markdown, and the converted output is far cleaner than pasted rich text.
- Writing a README from an existing page. Convert a product page or wiki article into the Markdown GitHub renders.
- Cleaning up rich-text editor output. WYSIWYG editors emit deeply nested HTML with inline styles; converting strips it back to structure.
- Preparing content for an LLM prompt. Markdown is markedly more token-efficient than the equivalent HTML, and the size-reduction figure shows how much you save.
- Extracting a table from a page. Convert just the table element to get a Markdown table you can paste into a document.
The reverse direction is Markdown to HTML, which renders a safe preview. To turn HTML into a React component instead, use HTML to JSX, and the HTML Formatter tidies the source before conversion.
Privacy
Conversion runs entirely in your browser using Turndown. The HTML is not uploaded, and no request is made to any URL it contains — images and links are treated as text, never fetched. Usage analytics record only the style settings and table count.
Frequently Asked Questions
Does it really convert tables, or leave them as HTML?
It converts them into proper Markdown pipe tables, including alignment from the align attribute. This needs explicit rules because Turndown targets CommonMark, which has no table syntax and passes tables through as raw HTML by default. You can turn the behaviour off if you want strict CommonMark.
What happens to a table with merged cells?
The grid is flattened and you get a warning saying so. Markdown tables are strictly rectangular, so rowspan and colspan cannot be represented at all. If the merging carries meaning, keep that one table as inline HTML — most Markdown renderers accept it.
Why did my styling disappear?
Because Markdown has no styling syntax. Inline style attributes, class names and alignment are all discarded, which is the point of converting: you keep the structure and drop the presentation. Anything conveyed purely by CSS becomes ordinary text.
Should I use ATX or Setext headings?
ATX, in almost every case. Setext underlining only expresses two levels, so any document with H3 headings ends up mixing both styles. Most Markdown linters and style guides also default to ATX.
When is reference link style worth using?
When URLs are long enough to make paragraphs hard to read, or when the same URL appears several times. Reference style moves the URLs to the bottom of the file and refers to them by label, keeping the prose scannable.
Are images downloaded or embedded?
Neither. The src attribute is copied as written, so a relative path such as /diagram.png stays relative and will need rewriting for wherever the Markdown ends up. No network request is made for any image.
How much smaller is the Markdown?
Typically 50 to 70% smaller for scraped page HTML, because wrapper divs, classes and inline styles all disappear. The size-reduction figure in the stats row is measured from your actual input rather than being an estimate.