HTML to Markdown Conversion Guide: Tools & Best Practices (2026)

Published

Converting HTML to Markdown is a essential skill for developers, technical writers, and content creators migrating between platforms. Whether you are moving a blog from WordPress to a static site, extracting content from a CMS, or preparing documents for AI processing, this guide covers every method and tool for HTML to Markdown conversion.


Why Convert HTML to Markdown?

HTML serves the web well, but it has drawbacks for content authoring and portability:

  • Readability — Markdown source is clean plain text. HTML source is cluttered with tags that obscure the content
  • Version control — Markdown diffs cleanly in Git. HTML diffs are noisy with tag changes mixed into content changes
  • Static site generators — Jekyll, Hugo, Next.js, Docusaurus, and Astro all use Markdown as their primary content format
  • AI and LLM compatibility — Markdown uses 60-80% fewer tokens than HTML while preserving document structure, making it ideal for feeding content to ChatGPT, Claude, and RAG pipelines
  • Platform independence — Markdown works everywhere: GitHub, GitBook, Obsidian, Notion, and any text editor
  • Focused writing — Markdown encourages you to think about content structure rather than visual styling

Quick Conversion: Online Tool (Easiest)

The fastest way to convert HTML to Markdown is using our free online HTML to Markdown converter. Just paste your HTML and get clean Markdown output instantly.

How it works:

  1. Copy your HTML source code (from browser DevTools, a saved file, or a CMS export)
  2. Paste it into the converter
  3. Click Convert to get clean Markdown output
  4. Copy the result and save it as a .md file

Powered by the Turndown library, it handles headings, paragraphs, lists, links, images, code blocks, tables, and blockquotes accurately. All processing happens in your browser — nothing is uploaded to a server.

Best for: One-off conversions, quick migrations, content that fits in your clipboard.

Tool Comparison: Which Converter Should You Use?

ToolTypeBest ForBatch Supportlearning Curve
Online ConverterWeb appQuick one-off conversionsNoNone
TurndownJavaScript libraryWeb apps, Node.js scriptsYesLow
PandocCommand lineLarge-scale batch conversionYesMedium
html2textPython libraryPython projects, scriptingYesLow
markedJavaScript libraryLightweight conversionYesLow

Method 1: Turndown (JavaScript / Node.js)

Turndown is the most popular JavaScript library for HTML to Markdown conversion. It powers our online converter and many other tools in the ecosystem.

Installation

npm install turndown

Basic Usage

const TurndownService = require('turndown');
const turndownService = new TurndownService();

const html = `
<h1>Hello World</h1>
<p>This is a <strong>paragraph</strong> with some <em>italic text</em>.</p>
<ul>
  <li>Item one</li>
  <li>Item two</li>
</ul>`;

const markdown = turndownService.turndown(html);
console.log(markdown);
// Output:
// # Hello World
//
// This is a **paragraph** with some *italic text*.
//
// * Item one
// * Item two

Custom Rules

Turndown lets you define custom conversion rules for HTML elements it does not handle by default:

turndownService.addRule('strikethrough', {
  filter: ['del', 's', 'strike'],
  replacement: function (content) {
    return '~~' + content + '~~';
  }
});

Preserving HTML Elements

By default, Turndown removes HTML elements that have no Markdown equivalent. You can keep specific elements as raw HTML:

turndownService.keep(['div', 'span', 'sup', 'sub']);
const markdown = turndownService.turndown(html);

Method 2: Pandoc (Command Line)

Pandoc is the Swiss Army knife of document conversion. It handles HTML to Markdown conversion with high fidelity and supports batch processing.

Single File Conversion

pandoc input.html -o output.md

Batch Convert All HTML Files

# Convert all HTML files in the current directory
for file in *.html; do
  pandoc "$file" -o "${file%.html}.md"
done

Convert with Specific Markdown Dialect

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

# Output CommonMark
pandoc input.html -f html -t commonmark -o output.md

Recursive Directory Conversion

# Find and convert all HTML files recursively
find . -name "*.html" -exec pandoc {} -o {}.md \;

Method 3: html2text (Python)

For Python projects, html2text is a lightweight library that converts HTML to Markdown-formatted text.

Installation

pip install html2text

Basic Usage

import html2text

converter = html2text.HTML2Text()
converter.body_width = 0  # Disable line wrapping

html = "<h1>Hello</h1><p>This is a <strong>test</strong>.</p>"
markdown = converter.handle(html)
print(markdown)
# Output:
# # Hello
#
# This is a **test**.

Batch Conversion Script

import os
import html2text

converter = html2text.HTML2Text()
converter.body_width = 0

input_dir = "./html_files"
output_dir = "./markdown_files"
os.makedirs(output_dir, exist_ok=True)

for filename in os.listdir(input_dir):
    if filename.endswith(".html"):
        with open(os.path.join(input_dir, filename)) as f:
            html = f.read()
        markdown = converter.handle(html)
        output_name = filename.replace(".html", ".md")
        with open(os.path.join(output_dir, output_name), "w") as f:
            f.write(markdown)
        print(f"Converted: {filename} -> {output_name}")

Method 4: marked (JavaScript, Lightweight)

If Turndown feels heavy, marked is a faster, lighter alternative for basic conversions:

npm install marked
const { marked } = require('marked');
const html = '<h1>Hello</h1><p>World</p>';
const markdown = marked.parse(html);

Note: marked is primarily an HTML-to-Markdown renderer (Markdown in, HTML out), but it can be used in reverse with custom plugins.

CMS Migration Workflows

WordPress to Markdown

WordPress stores content as HTML in its database. Here is a step-by-step migration workflow:

  1. Export your posts — Use WordPress's built-in XML export (Tools > Export > All Content)
  2. Convert XML to HTML — Parse the XML to extract post content as HTML
  3. Convert HTML to Markdown — Use Turndown or Pandoc to convert each post
  4. Add front matter — Add YAML front matter with title, date, and tags for your static site generator

Automated tool: The exitwp Python tool can automate the entire WordPress-to-Markdown pipeline.

Ghost to Markdown

Ghost already uses a Markdown editor, but exported content may include Ghost-specific HTML:

  1. Export from Ghost — Use Ghost's JSON export feature
  2. Extract post content — Parse the JSON to access the HTML body
  3. Convert HTML to Markdown — Run through Turndown or Pandoc
  4. Clean up Ghost shortcodes — Replace []{.kg-card-*} markers with standard Markdown

Medium to Markdown

Medium does not offer a native Markdown export. Here is the workflow:

  1. Export your Medium data — Request a full export from Medium settings
  2. Extract article content — The export includes HTML versions of your posts
  3. Convert HTML to Markdown — Use our online converter or Pandoc for batch processing
  4. Fix Medium-specific elements — Replace embeds with links, clean up image references

Notion to Markdown

Notion supports Markdown export natively, but for complex pages with databases:

  1. Use Notion's export — Settings > Export > Markdown & CSV
  2. Clean up the output — Notion adds extra blank lines and may simplify complex blocks
  3. Convert any remaining HTML — Use our converter for any embedded HTML elements

Common Pitfalls and Solutions

1. Nested Tables

HTML tables with colspan and rowspan do not convert to Markdown cleanly because Markdown tables do not support cell merging.

Solution: Convert complex tables to HTML tables within your Markdown file, or restructure them as simpler Markdown tables.

2. Inline Styles

HTML inline styles (style="color: red;") are lost in Markdown conversion because Markdown has no styling syntax.

Solution: Clean your HTML first by removing inline styles. Use CSS classes instead and style them separately in your static site generator's theme.

3. Embedded Content

<iframe>, <video>, <audio>, and <object> elements have no Markdown equivalent.

Solution: Convert these to raw HTML that Markdown pass-through will preserve, or replace with links to the original content.

4. Image Paths

Relative image paths in HTML may break after conversion if your file structure changes.

Solution: Convert all image URLs to absolute URLs before conversion, or update paths after conversion to match your new directory structure.

5. Code Blocks Without Language Tags

HTML <pre><code> blocks without a language class convert to plain code blocks without syntax highlighting.

Solution: Manually add language identifiers after conversion: ```javascript instead of just ```.

Best Practices for Clean Conversion

  • Clean your HTML first — Remove inline styles, unnecessary divs, JavaScript, and comments before converting for cleaner Markdown output
  • Handle images before conversion — Download images and update URLs to point to your new location
  • Check table conversion — Complex tables with merged cells will not convert perfectly. Review and fix manually
  • Preserve code blocks — Use a converter that properly handles <pre> and <code> elements with language detection
  • Convert in batches — For large migrations, write scripts to automate the process rather than converting files one by one
  • Validate the output — Always preview your converted Markdown in a Markdown editor to catch formatting issues
  • Version control your content — After conversion, commit your Markdown files to Git to track changes and enable collaboration

Converting Markdown to Other Formats

Once your content is in Markdown, you can convert it further using our free tools:

Related Guides

Frequently Asked Questions