HTML to Markdown: The Conversion Map
Whether you're migrating a blog to a static site generator, converting documentation, or scraping content, you need to convert HTML to Markdown. Here's how every tag maps.
Tag-to-Markdown Mapping
| HTML | Markdown |
|---|---|
<h1>Title</h1> | # Title |
<h2>Section</h2> | ## Section |
<p>Text</p> | Text (blank line before/after) |
<strong>bold</strong> | **bold** |
<em>italic</em> | *italic* |
<a href="url">text</a> | [text](url) |
<img src="url" alt="text"> |  |
<code>inline</code> | `inline` |
<pre><code>block</code></pre> | Triple backticks |
<ul><li>item</li></ul> | - item |
<ol><li>item</li></ol> | 1. item |
<blockquote>text</blockquote> | > text |
<hr> | --- |
<del>strikethrough</del> | ~~strikethrough~~ |
Programmatic Conversion
// Node.js — Turndown
import TurndownService from 'turndown';
const turndown = new TurndownService({
headingStyle: 'atx', // # style headings
codeBlockStyle: 'fenced', // ``` style code blocks
bulletListMarker: '-',
});
const html = '<h1>Hello</h1><p>World</p>';
const markdown = turndown.turndown(html);
// "# Hello\n\nWorld"# Python — markdownify
from markdownify import markdownify
html = '<h1>Hello</h1><p><strong>World</strong></p>'
md = markdownify(html, heading_style='ATX')
# '# Hello\n\n**World**'Handling Tables
<table>
<thead>
<tr><th>Name</th><th>Role</th></tr>
</thead>
<tbody>
<tr><td>Alice</td><td>Admin</td></tr>
</tbody>
</table>
→ Markdown:
| Name | Role |
|-------|-------|
| Alice | Admin |Edge Cases
- Nested lists: Indent with 2-4 spaces in Markdown
- Inline styles/classes: Stripped (Markdown has no styling)
- Iframes/embeds: No Markdown equivalent — keep as raw HTML
- Complex tables: Markdown tables don't support colspan/rowspan — simplify or keep as HTML
Convert now: HTML to Markdown — paste HTML, get clean Markdown instantly.