← All tools

HTML to Markdown Converter

Convert HTML into clean GitHub-flavored Markdown — headings, lists, tables, code blocks, links and images. Runs entirely in your browser.

This tool runs entirely in your browser. Your input is never uploaded.

Advanced options
HTML input
Markdown result

What this tool does

This tool rewrites HTML markup as GitHub-flavored Markdown. Paste a snippet you copied from a rendered page, drop in a saved .html file, or start from the built-in sample, and the Markdown appears next to the input as you type.

Common uses: moving documentation out of a CMS and into a repository, turning a saved web article into a Markdown note, converting tables from a spreadsheet export into a README, or cleaning up markup before pasting it into an issue tracker.

Parsing and conversion happen in the current browser tab. The markup is never uploaded, and no part of the page you paste is executed while it is being converted.

How to use it

  1. Paste HTML into the left pane, or use Load file to read a saved .html page. Load sample fills in a document that exercises every conversion rule.
  2. If the markup uses relative links or images, enter the page address in Base URL so href and src values become absolute.
  3. Open Advanced options if you want a different list marker, code block style, or link style, or if you want to narrow the conversion to part of the document.
  4. Copy the result or download it as a .md file. The download name is taken from the loaded file name, otherwise it is converted.md.

How the conversion works

  • Headings and paragraphs — <h1> to <h6> become ATX headings (# to ######). Paragraphs are separated by blank lines, and <br> becomes a hard line break with two trailing spaces.
  • Lists — nested <ul>/<ol> keep their structure, with three spaces after each marker and four-space indentation per level. <input type="checkbox"> items become GFM task list items (- [ ] and - [x]).
  • Tables — a table with a heading row becomes a GFM table, and column alignment is read from the align attribute or text-align in the style. A table without a heading row gets an empty heading row, because GFM has no other way to express it.
  • Code — <pre><code class="language-js"> becomes a fenced block with the language tag, and the fence gets longer whenever the code itself contains one, so the block never breaks. Inline <code> is wrapped in as many backticks as it needs.
  • Links and images — links become [text](url) and images become ![alt](url), keeping the title attribute when there is one. With the reference style, links are collected as [1], [2] and defined at the end of the document. An image whose src is a placeholder (data: URI or missing) takes its real URL from data-src, data-original, or data-lazy-src, and a javascript: target is dropped so its text stays plain.
  • Blockquotes and emphasis — <blockquote> becomes >, <strong>/<b> becomes **, <em>/<i> becomes *, and <del>/<s>/<strike> becomes ~~.
  • Ignored elements — script, style, noscript, template, head, title, iframe, svg, and canvas are dropped along with their contents. Unknown tags are removed and their text is kept.
  • Text cleanup — entities are decoded (&amp; becomes &), non-breaking spaces are normalised to spaces, runs of blank lines collapse, and the result ends with a single newline.

Advanced options

  • Bullet marker — -, *, or +. The default is -.
  • Code blocks — fenced (```) or indented with four spaces.
  • Links — inline [text](url) or reference [text][1] definitions.
  • Remove elements — a CSS selector list such as nav, footer, .ad whose matches are deleted before conversion.
  • Keep only elements — a CSS selector such as article or .post-content that limits the conversion to those subtrees. When one match sits inside another, only the outer one is converted.

Limits worth knowing

  • The output is text, and it is not sanitised. Markdown characters are escaped with backslashes so that 5 * 3 stays 5 \* 3 and a leading 1. does not become a list, and code inside a code block is never escaped. Text that already looked like an HTML tag in the source is emitted as it is, so treat converted output from an untrusted page the same way you would treat any pasted content.
  • Relative URLs stay relative unless you fill in Base URL. The tool does not fetch the page, so it cannot know where the markup came from.
  • Tables have no rowspan or colspan in GFM. A colspan becomes empty cells, and a rowspan leaves the covered columns empty in the following rows, so the grid stays rectangular either way. The text of a spanning cell appears on the row where the source put it.
  • Elements hidden with CSS are converted too. Unticking a menu with display: none still produces its text; use Remove elements for that.
  • Files are read as UTF-8. A page saved in GBK, Big5 or Shift-JIS can arrive as mojibake — run it through the Mojibake Fixer first, then convert.
  • Input is capped at 2 MB. Parsing happens on the page's main thread, because the browser's HTML parser is not available inside a web worker, and much larger inputs would freeze the tab.

Privacy

The HTML you paste is parsed in your browser and is never sent to this site's server. The parsed document is inert: scripts, styles, and remote images in the input are not executed or loaded during conversion. Note that the markup itself can still contain text you would rather not paste into a third-party page — an internal URL, a session token in a query string, or a customer name — so trim it first when it matters.

Frequently asked questions

Does it keep the original HTML when it cannot convert something?

No. Unknown tags are dropped and only their text is kept, so the output never silently carries raw markup from the source. The one exception is text that was already escaped in the source, such as &lt;div&gt;, which comes out as the literal characters <div>.

Why is my Markdown full of backslashes?

Backslash escapes keep the text you pasted from turning into Markdown syntax. Without them, a heading that reads 1. Hello would render as a list item. If you are writing the Markdown by hand afterwards, the escapes are safe to remove.

Can I convert only the article body of a whole page?

Yes. Paste the page source and put a CSS selector in Keep only elements, such as article or main. Pair it with Remove elements to drop navigation, footer, and ad blocks first.

They point at whatever the source HTML said. Fill in Base URL to make relative links absolute, and check the result before publishing it.

Related tools

A growing collection of browser-only tools. Your data stays on your device whenever the browser can handle the task.