🍱 Lunchbox Hands

HTML β†’ Markdown Converter

Convert HTML into clean, readable Markdown

Paste any HTML β€” a page fragment, a CMS export, or a raw HTML file β€” and get clean, readable Markdown instantly. Supports headings, lists, tables, code blocks, blockquotes, links, images, and more. Everything runs in your browser; nothing is uploaded.

Bullet style
Markdown will appear here…

Why convert HTML to Markdown?

Markdown has become the default writing format for developer documentation, README files, wikis, and content-management systems that prioritize readability. HTML, on the other hand, is the lingua franca of the web β€” every CMS, email template, and blog platform ultimately produces it. When you need to move content between these two worlds, hand-converting tags to Markdown syntax is tedious, error-prone, and slow.

Common scenarios where HTML-to-Markdown conversion saves time include migrating blog posts from a CMS to a static-site generator like Astro, Hugo, or Eleventy; converting email newsletter HTML to Markdown for archiving; importing documentation from a web app into a GitHub wiki or a Notion-style notes app; and cleaning up pasted HTML in a Slack or Discord message into something more readable.

How the conversion works

This tool uses the browser's native DOMParser API to parse the input HTML into a real DOM tree β€” exactly as a browser would. It then walks the tree recursively, converting each element to its Markdown equivalent. Because it operates on a live DOM rather than parsing HTML with regular expressions, it handles malformed, nested, and deeply structured HTML reliably.

Block-level elements like headings, paragraphs, blockquotes, and lists are separated by blank lines (two newlines), which is what Markdown renderers use to distinguish blocks. Inline elements like bold, italic, code, and links are converted in place. Script and style tags β€” together with their full content β€” are stripped before conversion so they never appear in the output.

Plain text nodes are checked for Markdown-special characters (asterisks, underscores, backticks, brackets, tildes) and those characters are escaped with a backslash so they render literally. Characters inside <code> and <pre><code> blocks are never escaped, since they are wrapped in backtick fences.

How to use this tool

  1. Paste your HTML into the left pane. Conversion runs live on every keystroke.
  2. Adjust the bullet style (- or *) and the GFM toggle to match your target renderer.
  3. Review the Markdown in the right pane and copy or download the result.

GFM tables and strikethrough

When the GFM toggle is on (the default), HTML tables are converted to GitHub-Flavored Markdown pipe tables. The first table row becomes the header, and a delimiter row of dashes separates it from the body. Column alignment hints in the HTML are not currently carried over β€” all columns use the default (left) alignment.

The <del> and <s> HTML tags are converted to ~~strikethrough~~ syntax when GFM is enabled. If you are targeting a Markdown renderer that does not support GFM (CommonMark strict, for example), disable the GFM toggle to omit strikethrough markers and skip table conversion.

If you need to go the other direction β€” from Markdown to HTML β€” use the Markdown β†’ HTML Converter. And if you want to see how your converted Markdown renders, paste it into the Markdown Preview tool.

Nested lists and indentation

Nested lists are one of the trickiest HTML structures to convert cleanly. This tool indents each nesting level by two spaces, which is the convention recognised by virtually every Markdown renderer including GitHub, GitLab, and CommonMark-compliant parsers. A nested <ul> inside an <li> becomes an indented block of bullet items; a nested <ol> inside an <li> becomes an indented block of numbered items.

Ordered list items all use 1. as their marker. Markdown renderers automatically calculate the sequential numbers, so using 1. throughout is both valid and recommended by the CommonMark specification.

Code blocks and language detection

A <pre><code> element is converted to a fenced code block β€” three backtick lines wrapping the content. If the inner <code> element has a class like language-js or language-python (the convention used by Prism.js, Highlight.js, and most syntax highlighters), the language identifier is extracted and placed after the opening fence. This lets Markdown renderers apply syntax highlighting when they re-render the output.

Related tools

  • Convert in the opposite direction with the Markdown β†’ HTML Converter β€” turn Markdown back into HTML with a live preview.
  • Preview your converted Markdown with the Markdown Preview tool β€” paste the output and see it rendered side-by-side.
  • Need to build a data table? The Markdown Table Generator lets you build GFM pipe tables visually in a grid and copy the ready-to-use Markdown.

Frequently asked questions

What HTML elements are supported?

The converter handles all the elements you encounter in real-world HTML: headings (h1–h6), paragraphs, line breaks, horizontal rules, blockquotes (including nested), ordered and unordered lists with unlimited nesting depth, inline code, fenced code blocks (with language detection from the CSS class), bold, italic, strikethrough (GFM), links, and images. Block containers like div, section, and article are treated as generic block-level wrappers. Script and style tags β€” along with their entire content β€” are stripped completely.

Does it handle tables?

Yes. When the GFM option is enabled (the default), HTML tables are converted to GitHub-Flavored Markdown pipe tables with a header row and a delimiter row of dashes. The tool reads thead and tbody sections correctly. If you need to produce Markdown for a renderer that does not support GFM tables, uncheck the GFM toggle and tables will be rendered as plain text instead.

Is my HTML uploaded anywhere?

No. Everything runs entirely in your browser using the native DOMParser API. No data is sent to a server, no network requests are made, and nothing is stored. Your HTML stays on your machine. The tool works offline once the page is loaded.

Can I convert a whole web page?

Yes β€” with some expectations to set. Open the page in your browser, right-click and choose "View Page Source" or use DevTools to copy the outer HTML, then paste it here. The converter strips script and style blocks automatically, so you'll get the content elements. Keep in mind that heavily JavaScript-rendered pages may have minimal HTML in source; for those, copy the rendered HTML from the Elements panel in DevTools instead.

Why does my output have extra backslashes?

Markdown uses characters like *, _, `, [, and ] as syntax markers. When these appear in plain text content β€” not as intentional formatting β€” the converter escapes them with a backslash so they render literally. This is correct Markdown behaviour. If you see over-escaping in a specific case, the source HTML may be using those characters in a way the converter interprets as plain text. Code inside &lt;code&gt; or &lt;pre&gt;&lt;code&gt; elements is never escaped.

Get weekly dev tools and tips