14 min read

How to Convert HTML to Markdown: Complete Guide 2026

Everything you need to convert HTML to Markdown and back. Includes a complete syntax mapping table, code examples in JavaScript and Python, edge cases, and the best free tools.

Why Convert HTML to Markdown

HTML is the language of the web. It is what browsers render, what CMSs store, and what WYSIWYG editors produce. But HTML is verbose by design. A simple bold paragraph requires opening and closing tags, attributes, and nesting rules that add visual noise when you just want to read or write content.

Markdown solves this by giving you a lightweight syntax that maps directly to HTML but is dramatically easier to read and write. Instead of <h2>Title</h2>, you write ## Title. Instead of <a href="url">link</a>, you write [link](url). The content stays the same. The cognitive overhead drops to near zero.

Converting HTML to Markdown is a common task in these situations:

The challenge is that HTML is more expressive than Markdown. Not every HTML element has a Markdown equivalent. A good converter handles the common cases cleanly and gives you sensible options for the edge cases. Let us walk through exactly how to do this.

The Complete HTML-to-Markdown Syntax Mapping

This table covers every HTML element that has a direct Markdown equivalent. Bookmark it as a reference. If you want to test these mappings interactively, paste any HTML snippet into the QTool HTML to Markdown converter and see the output instantly.

HTML Markdown Notes
<h1> to <h6># to ###### One # per heading level
<p>Plain text + blank lineParagraphs separated by empty lines
<strong> / <b>**text**Double asterisks or underscores
<em> / <i>*text*Single asterisks or underscores
<del> / <s>~~text~~GFM extension
<a href="url">[text](url)Title attr: [text](url "title")
<img src="url">![alt](url)Alt text becomes the label
<ul><li>- itemAlso * or + as bullet
<ol><li>1. itemNumbers auto-increment
<blockquote>> textNest with > > text
<code>`code`Inline code
<pre><code>```lang ... ```Fenced code block
<hr>---Also *** or ___
<br>Two trailing spaces or \Line break within paragraph
<table>Pipe tableGFM extension (see below)
<input type="checkbox">- [x] / - [ ]GFM task lists

Table Conversion Example

HTML tables convert to GitHub Flavored Markdown (GFM) pipe tables. This is one of the trickiest conversions because HTML tables support features like colspan, rowspan, and nested tables that pipe tables cannot represent.

<!-- HTML -->
<table>
  <thead>
    <tr><th>Name</th><th>Role</th><th>Status</th></tr>
  </thead>
  <tbody>
    <tr><td>Alice</td><td>Admin</td><td>Active</td></tr>
    <tr><td>Bob</td><td>Editor</td><td>Inactive</td></tr>
  </tbody>
</table>

Converts to:

| Name  | Role   | Status   |
|-------|--------|----------|
| Alice | Admin  | Active   |
| Bob   | Editor | Inactive |

You can also generate these tables from scratch using the QTool Markdown Table Generator, which gives you a visual grid editor for creating perfectly aligned pipe tables.

Key Insight

Not all HTML converts cleanly. Elements like <div>, <span>, <form>, <iframe>, and any tag with inline styles have no Markdown equivalent. Good converters strip them or pass them through as raw HTML. Know what your converter does with unsupported elements before running a bulk conversion.

Using Online Converter Tools

For one-off conversions or quick content extraction, a browser-based tool is the fastest option. No installation, no dependencies, no configuration.

QTool HTML to Markdown is a free converter that runs entirely in your browser. Paste HTML on the left, get Markdown on the right. It handles all the common elements from the mapping table above, including tables, nested lists, code blocks, and images. Because it processes everything client-side with JavaScript, your HTML never leaves your machine.

After converting, you can verify the output by pasting the generated Markdown into the QTool Markdown Preview tool, which renders it as HTML so you can visually confirm the conversion preserved your content correctly.

When to use an online tool

When to use a programmatic approach

Converting HTML to Markdown with JavaScript

Turndown is the standard JavaScript library for HTML-to-Markdown conversion. It creates a DOM tree from your HTML, walks each node, and applies conversion rules to produce clean Markdown output. It works in both Node.js and the browser.

Installation

npm install turndown
# or
yarn add turndown

Basic Usage

import TurndownService from 'turndown';

const turndown = new TurndownService({
  headingStyle: 'atx',        // # style headings (not underline)
  codeBlockStyle: 'fenced',   // ``` blocks (not indented)
  bulletListMarker: '-',      // - for unordered lists
});

const html = `
  <h2>Project Setup</h2>
  <p>Install the <strong>dependencies</strong> first:</p>
  <pre><code class="language-bash">npm install</code></pre>
  <ul>
    <li>Node.js 18+</li>
    <li>npm or yarn</li>
  </ul>
`;

const markdown = turndown.turndown(html);
console.log(markdown);

Output:

## Project Setup

Install the **dependencies** first:

```bash
npm install
```

- Node.js 18+
- npm or yarn

Custom Rules

Turndown lets you add custom rules for any HTML element. This is essential when converting HTML from a specific CMS or application that uses custom classes or non-standard markup.

// Convert custom callout divs to blockquotes
turndown.addRule('callout', {
  filter: (node) => {
    return node.nodeName === 'DIV'
      && node.classList.contains('callout');
  },
  replacement: (content) => {
    return '\n> ' + content.trim().replace(/\n/g, '\n> ') + '\n';
  }
});

// Strip all <script> and <style> tags completely
turndown.remove(['script', 'style']);

GFM Tables Plugin

Turndown does not convert tables by default. Install the GFM plugin to add table support along with strikethrough, task lists, and other GitHub Flavored Markdown features.

import { gfm } from 'turndown-plugin-gfm';

turndown.use(gfm);

const html = '<table><tr><th>Name</th><th>Age</th></tr><tr><td>Alice</td><td>30</td></tr></table>';
console.log(turndown.turndown(html));
// | Name  | Age |
// |-------|-----|
// | Alice | 30  |

Converting HTML to Markdown with Python

Python developers have two solid options: markdownify for simple conversions and html2text for more aggressive cleanup.

markdownify

pip install markdownify
from markdownify import markdownify as md

html = """
<h1>Welcome</h1>
<p>This is a <strong>test</strong> with a
<a href="https://example.com">link</a>.</p>
<ul>
  <li>Item one</li>
  <li>Item two</li>
</ul>
"""

result = md(html, heading_style="ATX", bullets="-")
print(result)

Output:

# Welcome

This is a **test** with a [link](https://example.com).

- Item one
- Item two

html2text

pip install html2text
import html2text

converter = html2text.HTML2Text()
converter.body_width = 0          # No line wrapping
converter.protect_links = True    # Don't break long URLs
converter.ignore_images = False   # Include image references

result = converter.handle(html)
print(result)

The key difference: markdownify aims for a one-to-one mapping that preserves the original structure. html2text is more opinionated and aggressively strips formatting to produce cleaner, more readable output. Choose based on whether you need structural fidelity or readability.

Command-Line Conversion with Pandoc

Pandoc is the Swiss Army knife of document conversion. It converts between dozens of formats, including HTML to Markdown, and handles edge cases that simpler tools miss.

# Install
brew install pandoc          # macOS
apt install pandoc           # Ubuntu/Debian
choco install pandoc         # Windows

# Convert a file
pandoc input.html -f html -t markdown -o output.md

# Convert from stdin
curl -s https://example.com | pandoc -f html -t markdown

# Use GitHub Flavored Markdown output
pandoc input.html -f html -t gfm -o output.md

# Batch convert all HTML files in a directory
for f in *.html; do
  pandoc "$f" -f html -t gfm -o "${f%.html}.md"
done

Pandoc is the best choice for CMS migrations where you need to convert hundreds or thousands of HTML files. It handles complex nesting, metadata extraction, and produces consistently clean output. For formatting the source HTML before converting, you can clean it up with the QTool HTML Beautifier to make the structure easier to inspect.

Edge Cases and Gotchas

The happy path of HTML-to-Markdown conversion is straightforward. The edge cases are where things get interesting. Here are the patterns that trip up converters and developers.

1. Inline Styles and Classes

Markdown has no concept of CSS. Inline styles like <span style="color:red">text</span> are silently stripped by most converters. If color, font size, or custom styling matters, you lose it in the conversion. The workaround is to keep the raw HTML in your Markdown file, since most Markdown renderers pass through HTML unchanged.

2. Nested Lists

Nested lists are the single most error-prone conversion. HTML allows arbitrary nesting of <ul> and <ol> elements. Markdown requires precise indentation (typically 2 or 4 spaces) to indicate nesting level. Off-by-one indentation errors cause Markdown parsers to flatten the list or break the structure entirely.

<!-- This HTML... -->
<ul>
  <li>Parent
    <ul>
      <li>Child
        <ul>
          <li>Grandchild</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<!-- ...must become exactly this: -->
- Parent
  - Child
    - Grandchild

3. Mixed Content in Paragraphs

HTML allows complex inline content: images inside links, links inside bold text, code spans containing special characters. Converters must handle combinations like <a href="url"><strong>bold link</strong></a>, which becomes [**bold link**](url). Not all converters get this right.

4. Empty Tags and Whitespace

WYSIWYG editors love inserting empty <p> tags, <br><br> sequences, and non-breaking spaces (&nbsp;). Good converters normalize this whitespace. Bad converters produce Markdown with excessive blank lines or literal &nbsp; strings.

5. HTML Entities

Entities like &amp;, &lt;, &gt;, &mdash;, and &copy; need to be decoded to their literal characters in Markdown. The exception is characters that have special meaning in Markdown (*, _, [, ]), which may need to be escaped with a backslash.

6. Code Blocks with Language Hints

HTML code blocks often indicate the language via a class: <pre><code class="language-python">. Good converters extract this class and produce a fenced block with the language identifier: ```python. If your converter does not handle this, you lose syntax highlighting metadata.

Converting Markdown Back to HTML

The reverse conversion -- Markdown to HTML -- is simpler and more reliable. Markdown is a subset of HTML's expressiveness, so every Markdown construct has an unambiguous HTML representation.

JavaScript (marked)

import { marked } from 'marked';

const md = '## Hello **World**\n\nA [link](https://example.com).';
const html = marked.parse(md);
// <h2>Hello <strong>World</strong></h2>
// <p>A <a href="https://example.com">link</a>.</p>

Python (markdown)

import markdown

md_text = "## Hello **World**\n\nA [link](https://example.com)."
html = markdown.markdown(md_text)
print(html)

For quick testing without writing code, use the QTool Markdown to HTML converter to see your Markdown rendered as HTML in real time. And if you want a full writing environment, the QTool Markdown Editor gives you a split-pane view with live preview as you type.

Best Practices for HTML-to-Markdown Conversion

1. Clean the HTML First

Before converting, strip out elements that have no Markdown equivalent: <script> tags, <style> blocks, tracking pixels, ad containers, and navigation chrome. The cleaner your input HTML, the cleaner your output Markdown. Use the QTool HTML Beautifier to reformat messy HTML so you can inspect and clean it before conversion.

2. Choose Your Markdown Flavor

Standard Markdown (CommonMark) does not support tables, task lists, or strikethrough. GitHub Flavored Markdown (GFM) adds these. Make sure your converter targets the flavor your rendering platform supports. Pandoc lets you specify the target with -t gfm, -t commonmark, or -t markdown_strict.

3. Validate the Output

Always render the converted Markdown and compare it visually against the original HTML. Automated conversion is imperfect. Check for broken links, missing images, flattened lists, and stripped formatting. The QTool Markdown Preview tool renders Markdown as HTML instantly so you can spot problems quickly.

4. Handle Images Separately

HTML-to-Markdown conversion changes image references from <img> tags to ![alt](url) syntax, but it does not download the images. If the image URLs point to the original server, they will break if the server goes down. For CMS migrations, download all images to a local assets directory and update the URLs in your Markdown files.

5. Preserve Metadata

HTML pages contain metadata in <title>, <meta> tags, and structured data that has no place in Markdown body content. If you are converting blog posts or documentation, extract this metadata into YAML front matter at the top of each Markdown file:

---
title: "How to Convert HTML to Markdown"
date: 2026-02-13
author: "Christian Bucher"
tags: ["html", "markdown", "conversion"]
---

# How to Convert HTML to Markdown

Article content starts here...

6. Test with Real Content

Do not test your conversion pipeline with simple, well-formed HTML. Test it with the messiest, most complex pages from your actual content. WYSIWYG editors produce surprisingly creative HTML. A converter that works on clean HTML may choke on real-world content from WordPress, Notion exports, or Google Docs HTML.

Convert Your HTML to Markdown Now

No sign-up, no data sent to servers, no ads. Paste your HTML and get clean Markdown output instantly.

Open HTML to Markdown Converter

Frequently Asked Questions

How do I convert HTML to Markdown?

The fastest way is to paste your HTML into a browser-based converter like QTool HTML to Markdown. It maps HTML tags to their Markdown equivalents instantly: headings become # symbols, bold becomes **, links become [text](url), and so on. For programmatic conversion, use libraries like Turndown (JavaScript), markdownify (Python), or Pandoc (command line).

Does Markdown support all HTML features?

No. Markdown covers common formatting like headings, bold, italic, links, images, lists, code blocks, and blockquotes. HTML features without a Markdown equivalent include tables with merged cells, colored text, embedded forms, iframes, and complex layouts. Most Markdown processors allow inline HTML as a fallback for unsupported features.

What is the best HTML to Markdown library for JavaScript?

Turndown is the most widely used JavaScript library for HTML-to-Markdown conversion. It parses HTML into a DOM tree and converts each element to its Markdown equivalent. It supports custom rules via plugins, handles edge cases like nested lists and code blocks, and works in both Node.js and the browser. Install it with npm install turndown.

Can I convert Markdown back to HTML?

Yes. Markdown-to-HTML conversion is simpler and more reliable than the reverse because Markdown has fewer features than HTML. Libraries like marked and markdown-it (JavaScript), Python-Markdown, and Pandoc all convert Markdown to clean HTML. You can use the free QTool Markdown to HTML converter to do this instantly in your browser.

Is it safe to convert HTML to Markdown online?

It is safe if the tool processes your HTML entirely in the browser without sending data to a server. QTool HTML to Markdown runs client-side using JavaScript, so your content never leaves your machine. You can verify this by checking the network tab in your browser developer tools. Avoid online converters that require you to upload files to their servers, especially if your HTML contains sensitive content.

Explore 269 Free Developer Tools

HTML to Markdown is just the start. QTool has free tools for JSON, CSS, regex, encoding, images, and much more. All browser-based, all private.

Browse All Free Tools
NT

Christian Bucher

We build free, privacy-first developer tools. Our mission is to make the tools you reach for every day faster, cleaner, and more respectful of your data.

Related Tools

CSS Box Shadow Generator · Markdown Table Generator - Free Online Tool · Emoji Picker & Search

Related Tools

Free JSON to YAML Converter · Free Markdown to PDF Converter · Free Git Diff Viewer

Built by Miguel

Need a custom tool or website?

From . Delivered in 24-48h. You own the code.

View Services →