HTML to Markdown
Convert HTML to clean Markdown instantly. Supports headings, links, images, lists, tables, bold, italic, and code blocks. Free, private, runs in your browser.
HTML Input
Markdown Output
How to convert HTML to Markdown
Paste HTML, convert, and copy or download the result.
- 01
Paste the HTML you want to convert
A snippet from a CMS editor, a saved page's source or an HTML email all work. The sample loaded on the page shows the elements the converter understands.
- 02
Convert and read the counts
The Markdown appears in the right-hand panel with a word and character count, which is handy for checking nothing large went missing. If the word count is far below the original article's, look for content that was inside an iframe or loaded by a script, since neither is in the pasted HTML.
- 03
Copy it, or download a .md file
Download saves a markdown file you can drop into a Hugo, Jekyll, Astro or Docusaurus content folder, or a GitHub repository.
What each HTML element becomes
The converter parses your HTML with the browser's own DOMParser, then walks the tree and writes Markdown for each element it recognises. Anything it doesn't recognise is unwrapped: the tag goes, the text stays.
| HTML | Markdown | Notes |
|---|---|---|
| <h1> to <h6> | # to ###### | Heading level kept |
| <strong>, <b> | **text** | |
| <em>, <i> | *text* | |
| <s>, <del> | ~~text~~ | GitHub-flavoured strikethrough |
| <a href title> | [text](url "title") | Title kept if present |
| <img src alt> |  | Width, height and srcset dropped |
| <ul>, <ol> | - item / 1. item | Nested lists come out flat |
| <pre><code class="language-js"> | ```js fenced block | Language read from the class |
| <blockquote> | > quoted line | |
| <table> | | pipe | table | | First row becomes the header; cells are plain text |
| <hr> | --- | |
| <div>, <span>, <section> | (removed) | Text inside is kept |
| <script>, <style> | (removed with content) | Code and CSS don't leak into the text |
Clean-up worth doing after you convert
Markdown can't express everything HTML can, so a little tidying is normal. Classes, inline styles, colours and font sizes are dropped by design. Embedded videos and iframes disappear completely, so search the original for <iframe and re-add those by hand, usually as a plain link or a shortcode your site generator supports.
Lists and tables need the most checking. A list inside another list is written at the same level as its parent, so indent the child items by two or four spaces. Table cells keep only their text, which means a link or bold word inside a cell becomes plain text, and a | character inside a cell will break the row until you escape it as \|.
A worked example from a CMS editor
Here's a typical paragraph copied from a WordPress post's code view, and what the converter writes for each part. Each row is one piece of the same snippet.
| HTML in | Markdown out |
|---|---|
| <h2>Getting started</h2> | ## Getting started |
| <p>Install the <strong>CLI</strong> first.</p> | Install the **CLI** first. |
| <p>See the <a href="/docs">docs</a>.</p> | See the [docs](/docs). |
| <div class="note"><p>Needs Node 20.</p></div> | Needs Node 20. |
| <img src="/a.png" alt="Setup screen" width="600"> |  |
Notice the fourth row. The styled note box loses its class, so it reads as an ordinary paragraph. If your site generator has a callout shortcode or admonition syntax, this is the kind of line to wrap by hand. Relative links such as /docs are also copied as is, so check they still resolve on the new site, or swap in absolute URLs.
Where HTML to Markdown helps
Moving a WordPress blog to a static site
Paste each post's HTML from the Text view, convert, and save the .md file into your new site's content folder.
Writing a README from existing docs
Turn an HTML help page into Markdown that renders on GitHub, then trim it down to what a README needs.
Feeding clean text to other tools
Markdown keeps headings and links but drops markup noise, which makes it a tidy format for notes apps and LLM prompts.