Convert HTML to Markdown

Paste any HTML fragment and get the matching Markdown source back. The HTML to Markdown converter walks the parsed DOM, downgrades semantic elements to their CommonMark equivalents, and writes a flat Markdown document. Headings, lists, links, images, blockquotes, inline emphasis and code blocks all map to their Markdown equivalents. The transform runs in your browser; nothing uploads.

Input
Line 1:1 LF cloud_done Saved locally
Result HTML to Markdown
0 lines 0 chars

HTML to Markdown, plain and predictable

HTML to Markdown conversion parses your input as HTML, walks the resulting DOM, and writes a Markdown document that round-trips back to the same semantic structure. <h1> through <h6> become # through ###### ATX headings. <ul> becomes a bullet list, <ol> becomes a numbered list, and nested lists indent two spaces per level. <strong> and <b> become **bold**; <em> and <i> become *italic*.

Links use [text](url) with the title attribute, when present, written as "title" after the URL. Images use ![alt](url). Inline <code> wraps in single backticks; <pre><code> wraps in a fenced block, and the language-XYZ class on the inner element survives as the fence language. Block quotes prefix every line with >. Tables convert to GitHub Flavored Markdown table syntax when the structure is rectangular; non-rectangular tables fall back to inline HTML.

Elements that have no clean Markdown equivalent (custom widgets, scripts, styles, form inputs) are written back as inline HTML so no information is silently lost. Class names, id attributes and inline styles are dropped, since Markdown has no place for them. For the inverse direction, see Markdown to HTML. To strip HTML out of plain text instead, see strip HTML tags.

How to use convert html to markdown

  1. 1Paste an HTML fragment into the input panel on the left.
  2. 2The Markdown source appears in the output panel on the right as you type.
  3. 3Click Copy in the output header to copy the Markdown.
  4. 4Click Download to save the result as an .md file.
  5. 5Drop the Markdown into a README, a wiki, or any CommonMark-aware editor.

Keyboard shortcuts

Drive TextResult without touching the mouse.

Shortcut Action
Ctrl FOpen the find & replace panel inside the input Plus
Ctrl ZUndo the last input change
Ctrl Shift ZRedo
Ctrl Shift EnterToggle fullscreen focus on the editor Plus
EscClose find & replace, or exit fullscreen
Ctrl KOpen the command palette to jump to any tool Plus
Ctrl SSave current workflow draft Plus
Ctrl PRun a saved workflow Plus

What this tool actually does

DOM walk, not regex

The HTML is parsed by the browser into a real DOM tree, then walked node by node. That means malformed input is auto-corrected the same way the browser would render it, and nested elements (a <strong> inside a <li> inside a <ul>) come out correctly nested in Markdown.

Headings, lists and emphasis

<h1> through <h6> become ATX headings. <ul> and <ol> become bullet and numbered lists, with nested lists indented two spaces per level. <strong>, <b>, <em>, <i>, <del> and <s> map to their Markdown emphasis forms.

Links, images, code blocks

Anchors become [text](url), with the title attribute carried as the optional quoted suffix. Images become ![alt](url). Inline <code> wraps in single backticks. <pre><code class="language-js"> wraps in a fenced block with js as the fence language.

Tables fall back when needed

A rectangular HTML table renders as a GFM Markdown table with header, separator and body rows. A table with merged cells (colspan, rowspan), a <caption>, or other features GFM cannot represent falls back to inline HTML so no data is lost.

Runs entirely in your browser

No upload, no server-side processing, no log of what you pasted. The DOM walk runs on every keystroke. Documents up to a few hundred kilobytes convert in under a second on a desktop browser.

Worked example

<h1> downgrades to #, <strong> and <em> downgrade to **bold** and *italic*, the <ul> becomes a bullet list.

Input
<h1>Heading 1</h1>
<p>A paragraph with <strong>bold</strong> and <em>italic</em>.</p>
<ul><li>one</li><li>two</li></ul>
Output
# Heading 1

A paragraph with **bold** and *italic*.

- one
- two

Settings reference

Behaviour Effect on output
Parse Browser HTML parser; malformed input is auto-corrected before the walk.
Headings <h1> through <h6> map to # through ###### ATX headings.
Lists <ul> bullet, <ol> numbered. Nested lists indent two spaces per level.
Emphasis <strong>/<b> become **bold**; <em>/<i> become *italic*; <del>/<s> become ~~strike~~.
Links and images <a> becomes [text](url); <img> becomes ![alt](url); title attribute carried as quoted suffix.
Code blocks Inline <code> wraps in backticks; <pre><code class="language-X"> wraps in a fenced block with X as the fence language.
Tables Rectangular tables map to GFM tables; merged-cell or captioned tables fall back to inline HTML.
Class/id/style Dropped. Markdown has no place for them.
Unknown elements Written back as inline HTML so no information is silently lost.

FAQ

How are tables converted?
A rectangular HTML table maps to a GFM Markdown table with a header row, a separator row, and one row per <tr>. Tables with colspan or rowspan, a <caption>, or any feature GFM cannot represent fall back to inline HTML so the data round-trips exactly.
What happens to inline styles and class names?
They are dropped. Markdown has no syntax for arbitrary classes, ids or styles, so the converter writes the semantic Markdown equivalent and discards the presentational attributes. If a class carries information the Markdown cannot capture, the element is written back as inline HTML to preserve it.
Does it work on a full HTML page?
Yes. The parser accepts a full <html> document or any fragment. Content inside <head> (title, meta, link, script, style) is dropped, since none of it has a Markdown equivalent. Content inside <body> walks the same way as a fragment.
Is the HTML sent anywhere?
No. The parse and walk run entirely in your browser via JavaScript. Nothing is uploaded, nothing is logged, no record of your text exists on our servers.
How do I go the other way?
Paste your Markdown into Markdown to HTML. That converter parses CommonMark plus GFM extensions and emits the matching HTML.