Markdown to HTML
Convert Markdown to HTML, then download a complete standalone styled HTML file or copy it as rich text to paste straight into Google Docs, Word, or email. Live styled preview, all in your browser.
- Free, no account
- No watermark
- No usage limit
About the Markdown to HTML
Paste Markdown into the box and you get the HTML back, plus a complete .html document you can download and a rich-text copy that pastes into Google Docs or an email as real formatting. Not a naked pile of tags you still have to wrap and style. A finished file: I ran a 344-line Markdown document of 24,757 bytes through it and got back a single 31,614-byte .html file with the whole stylesheet sitting inside it, nothing to send alongside and no folder of assets. Double-click it and it opens looking done. It all runs in your browser, so nothing you paste is uploaded.
Most converters stop at the tags. The two places this one quietly does more work than you would expect are the filename it picks for your download and the raw HTML it deliberately does not strip, and both are worth two minutes before you trust the output on anything that matters.
How to use
- Get the Markdown in. Type it, paste it, drag a file onto the box, or press "Open .md file". The picker is set to
.md,.markdown,.mdown,.txt, and anything your system labels as Markdown or plain text. Dragging skips that filter entirely, it reads whatever file you drop on it. - Pick a document style. Clean, GitHub, or Dark. The choice controls the styling baked into the file you download, not just the screen.
- Look at the Preview tab. It is not an approximation. The preview renders the exact document the Download button saves, same fonts, same spacing, same table borders.
- Take the output the way you need it. Copy HTML for a template or a CMS code view, Copy rich text for a word processor or an email, Download .html for the standalone file.
- Keep going. Nothing locks. An empty box, or one holding only spaces and tabs, shows no preview and no buttons at all, so a stale result never sits under fresh input.
The download filename comes from your first heading
The tool reads your first heading, puts it in the document title, and slugs it into the filename. First heading of any level, not the first #. Open with ###### Tiny heading first and follow it with # Big heading second and the file saves as tiny-heading-first.html, which surprises people who assume it hunts for the top-level one.
That sounds trivial and it is the part this tool used to get wrong, in three ways I can still reproduce. A README that opened with a paragraph, then a bash code block containing the line # Install the dependencies, then the real # Project Title, downloaded as install-the-dependencies.html, named after a shell comment. A title written the underline way with ===== beneath it was not seen as a heading at all, so the file came out as document.html with an empty browser tab. A linked heading like # [Project](https://example.com/docs/v2) dragged the whole URL into the name: project-https-example-com-docs-v2.html. All three now give you project-title.html, project-title.html and project.html, because the name is taken from the parsed document instead of from a second set of rules that has to be kept in step with it.
The honest limit on the same feature is the slug, which keeps letters a to z and digits and drops everything else. # Café Menu Résumé downloads as caf-menu-r-sum.html with the accents gone, and a heading written entirely in Japanese, Cyrillic or a single emoji leaves nothing at all and falls back to document.html. The title inside the file keeps every one of those characters correctly, it is only the filename that goes plain. There is no length trim either, a heading of six repeated clauses gave me a 311-character filename, past what most filesystems accept. Rename it, or write a shorter first heading.
Copy as rich text, into Docs, Word, or email
You draft in Markdown because it is fast to type, then the thing has to go in a shared Google Doc. Paste raw HTML there and the doc shows you literal tags, which helps nobody.
Copy rich text puts the formatted version on the clipboard instead, so Docs, Word, Outlook, Gmail and Notion receive real headings, bold, lists and links. Whether it survives is up to the destination. A plain-text field strips formatting on purpose and you get readable text, which is the right answer rather than a failure.
One behavior worth knowing because it used to be wrong. On a browser with no rich clipboard support the button falls back, and the fallback now copies the readable plain text and shows you a note saying it did. It used to copy the raw markup and still flash "Copied!", so people found out by pasting angle brackets into an email.
The three document styles
Clean is a wide reading column with generous line spacing, GitHub reproduces the bordered headings and striped table rows you know from a repo page, Dark is light text on a dark background with the code blocks retuned to match.
Each is a full stylesheet written into the file, which is why the download works anywhere with no network, and it costs 1,284 bytes for Clean, 1,359 for GitHub and 1,351 for Dark. So every download has a floor of about 1.3 KB however short the Markdown. On a one-line note that is most of the file. On a real README it rounds to nothing.
Your choice is remembered and the Share link carries it. I tested the thing that usually goes wrong there: opening someone's shared Dark link while you had GitHub saved leaves your saved GitHub untouched, the shared style applies to that visit and writes nothing of theirs into your browser. A style name the tool does not recognize falls back to Clean.
What GitHub Flavored Markdown leaves out
CommonMark plus the GitHub additions, both on, no switch. Pipe tables convert, ~~strikethrough~~ becomes <del>, - [ ] and - [x] become real disabled checkboxes, and a bare URL in a sentence becomes a link without brackets.
The extras that various apps bolt on are not in that set, and this is what each one produced when I fed it in:
- A footnote reference
[^1]stays exactly as typed, and the[^1]: The source.line below it converts into its own ordinary paragraph. - A definition list, meaning a term with
: The definition.under it, comes out as one paragraph holding both lines. - Inline math between dollar signs is untouched.
# Heading {.fancy #id}gives you<h1>Heading {.fancy #id}</h1>, curly braces and all, printed on the page.
None of that is a defect, it is the standard set doing what the standard says. It does mean that if your source leans on one app's private extension, you will read it back as text.
Line breaks catch nearly everyone, so here it is with a count. Twelve consecutive lines with no blank lines between them convert to one paragraph containing zero line breaks. Put two spaces at the end of those same twelve lines and you get one paragraph containing eleven breaks. A blank line starts a new paragraph, two trailing spaces force a break inside one.
Raw HTML passes straight through
Markdown is specified to let raw HTML through, and this converter honors that. Which makes for an odd asymmetry you should see before you publish anything: Tom & Jerry comes out as Tom & Jerry and "hello" comes out as "hello", both properly escaped, while <not-a-tag> comes out as <not-a-tag>, raw. Type angle brackets meaning them as words and the browser will read them as a tag and show you nothing.
The blunter version of the same thing: I pasted <script>alert(1)</script> and it landed in the downloaded file verbatim. There is no sanitizer here and there is not meant to be one.
The preview is the safe place, because nothing inside that pane is allowed to run. The file you download has no such protection, it is an ordinary HTML document. For your own README or newsletter draft none of this matters, you wrote it. For Markdown a stranger submitted that you plan to publish, run the output through a proper HTML sanitizer first, because this tool will not do that step for you.
Dropping a file that was not saved as UTF-8
Most converters read a dropped file as UTF-8 and accept whatever comes out. That is a real cost on Windows, where plenty of editors still save Windows-1252.
I fed both readers the same 14 bytes, a heading reading # Café Résumé saved the Windows way. This tool worked out the encoding from the bytes, gave the accents back intact, and printed a line telling me it had guessed and to check any accented name before shipping. The plain UTF-8 read of the same bytes produced # Caf then a replacement character, three of them in total, silently. A UTF-16 file is worse again, the naive read of that line came back with 14 embedded nulls and 5 replacement characters, which looks like deliberate output rather than a decode that failed.
A UTF-8 byte order mark is taken off the front and named. A UTF-32 file is refused with a sentence telling you to re-save it, rather than filling your box with rubbish. An empty file gives you an empty box and no error.
Where it gets slow
There is no length cap in the tool, and there is a speed curve, so both are worth stating. That 24,757-byte README converted in 3.4 ms. At 198,070 bytes it took 20 ms, at 792,286 bytes 88 ms, and at 3,169,150 bytes about 396 ms. Those came from driving the shipped converter outside a browser, so treat them as the shape of the curve, which is close to linear, rather than a benchmark of your laptop.
The number that actually affects you is none of those. It is that the whole document reconverts on every keystroke. Under a couple of hundred KB you will never notice. Paste a 3 MB file and try to edit it in the box and you are asking for a full reconversion per character typed, which is where typing starts to lag. Convert big files, edit them somewhere else.
Frequently asked questions
Why is my downloaded file called document.html?
Because the slug had nothing left to work with. The filename keeps only a to z and digits, so a heading written entirely in a non-Latin script, or in emoji, or in pure punctuation, empties out and the tool falls back to document. Same fallback if the file has no heading anywhere. The document title inside the file is still correct, so you can rename the download to match it.
My footnotes came out as [^1]. Is that broken?
No, footnotes are not part of CommonMark or the GitHub set, so the reference stays as typed and the definition below becomes a plain paragraph. If you need real footnotes in the exported file, write them as links to anchors, or convert first and add the markup afterwards.
Will the downloaded file look the same on someone else's computer?
Yes. The stylesheet is written into the file rather than linked from anywhere, which is what the 1,284 to 1,359 bytes of wrapper buys you. There is no second file to send, no external stylesheet to lose, and no network needed at the other end.
Can I load a file instead of pasting, and what types?
Three ways in. Drag it onto the box, use the "Open .md file" button, or copy a file in your file manager and paste it. The button's picker is limited to .md, .markdown, .mdown, .txt and files your system reports as Markdown or plain text. Dragging bypasses that list, so an oddly-named file that is really text still reads fine.
Is anything sent to a server?
No. Everything the page needs arrives with the page itself and nothing loads on demand, so once it has finished loading you can drop the network and keep converting, downloading and copying. That is why it is safe for an internal draft or an unpublished README.
What is the difference between Copy HTML and Copy rich text?
Copy HTML gives you the literal tags, for a template, a CMS code view, or a file you are hand-editing. Copy rich text gives you the rendered result for a word processor or an email client. Pasting the wrong one is why people end up staring at angle brackets in a Google Doc.