Skip to content

Markdown to HTML Converter

Convert Markdown to HTML in your browser — full GitHub Flavored Markdown, live preview, syntax highlighting. Export an HTML fragment, full document, or email-safe inline-styled HTML. 100% private, no upload.

No Tracking Runs in Browser Free
Everything runs in your browser. Your Markdown and HTML never leave your device.
Markdown
Preview
Custom CSS
HTML
Verified against CommonMark/GFM spec behavior, XSS-safe sandboxed rendering, and email-HTML inlining — Go Tools Engineering Team · Jun 5, 2026

What is Markdown to HTML Conversion?

Markdown to HTML conversion turns a plain-text document written in Markdown — with `#` for headings, `**bold**`, `- ` for lists, and `[text](url)` for links — into the HTML that browsers, content management systems, and email clients actually display. Markdown is designed to be readable as-is and easy to write, but a browser does not understand `# Heading`; it understands <h1>Heading</h1>. Conversion bridges that gap.

Under the hood, a Markdown processor first parses your source into an abstract syntax tree (AST) — a structured representation where a heading, a paragraph, a list, and a code block are distinct nodes with their content and attributes. It then serialises that tree to HTML, emitting the correct tags and nesting. Working through an AST, rather than swapping text with regular expressions, is what lets the converter handle nested lists, tables, and embedded HTML correctly and predictably. The two recognised grammars are CommonMark, the precise standard, and GitHub Flavored Markdown (GFM), which extends it with tables, task lists, strikethrough, and autolinks.

The reason you convert at all is that almost every publishing destination wants HTML, not Markdown. A static-site generator, a CMS rich-text field, an email template, and a browser tab all render HTML. So the typical workflow is to write in comfortable Markdown — a README, documentation, a blog draft, notes — and convert to HTML at the point of publishing. This tool does that conversion locally and shows a live preview, so you see the rendered result and can copy the exact HTML in the shape you need: a fragment, a full page, or email-ready inline-styled markup.

The reverse operation — HTML back to Markdown — is equally useful when you are migrating existing web content into a Markdown-based system. For that, switch to the HTML → Markdown tab or open the dedicated HTML to Markdown converter.

Markdown in:

  # Release Notes

  We shipped **tables** and `code`:

  | Feature | Status |
  | ------- | ------ |
  | GFM     | Done   |

  - [x] Parse to an AST
  - [ ] Profit

HTML out:

  <h1>Release Notes</h1>
  <p>We shipped <strong>tables</strong> and <code>code</code>:</p>
  <table>
    <thead><tr><th>Feature</th><th>Status</th></tr></thead>
    <tbody><tr><td>GFM</td><td>Done</td></tr></tbody>
  </table>
  <ul class="contains-task-list">
    <li class="task-list-item"><input type="checkbox" checked disabled> Parse to an AST</li>
    <li class="task-list-item"><input type="checkbox" disabled> Profit</li>
  </ul>

Key Features

Live Split-Pane Preview

Type Markdown on the left and watch it render on the right in real time, with the HTML output building below as you go. The preview renders in a sandboxed iframe, so what you see is what a browser will show — and pasted scripts can't run.

Full GitHub Flavored Markdown

Not just CommonMark — the full GFM superset: pipe tables, task lists (`- [x]`), strikethrough (`~~`), autolinked URLs, and fenced code blocks. A README or issue written for GitHub renders here exactly as it does there.

Syntax Highlighting

Label a fenced code block with its language (```js, ```python, ```sql) and the converter highlights it, wrapping tokens in spans with a language class on the <code> element. Pair with a highlight stylesheet on your page for colour.

Three Output Formats

Export an HTML fragment (body markup for a template or CMS), a Full document (a standalone page you can save as .html), or Email inline HTML with styles moved onto each element so Outlook and other clients render it correctly.

Custom CSS Panel

Inject your own CSS into the live preview to match a site's typography or mimic GitHub's README styling. Type rules like h1 { color: #0969da; } and the preview updates instantly, without touching the clean HTML you copy out.

GFM Syntax Cheat-Sheet

A quick reference for the syntax that produces HTML: `# H1` → heading, `**bold**` → <strong>, `*italic*` → <em>, `- item` → list, `1. item` → ordered list, `[text](url)` → link, `` `code` `` → inline code, ` ```lang ` → fenced code, `> quote` → blockquote, `| a | b |` → table, `- [ ]` → task list, `~~text~~` → strikethrough.

100% Private, In-Browser

Every conversion runs locally with JavaScript — your Markdown and HTML never leave your device, never hit a server, and work offline after the page loads. Safe for unpublished docs, internal READMEs, and embargoed release notes.

Examples

GFM table to an HTML <table>

| Tool | Speed |
| ---- | ----- |
| GFM  | Fast  |
<table>
<thead><tr><th>Tool</th><th>Speed</th></tr></thead>
<tbody><tr><td>GFM</td><td>Fast</td></tr></tbody>
</table>

GitHub Flavored Markdown pipe tables are not part of plain CommonMark, but this converter understands them and emits a proper semantic <table> with <thead> and <tbody> — ready to style or drop into a CMS.

Task list to checkbox HTML

- [x] Write the README
- [ ] Convert it to HTML
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" checked disabled> Write the README</li>
<li class="task-list-item"><input type="checkbox" disabled> Convert it to HTML</li>
</ul>

The GFM task-list syntax `- [x]` / `- [ ]` becomes real disabled checkbox inputs, exactly the way GitHub renders a checklist — so a copied README looks the same on your own page.

Fenced code block to highlighted <pre><code>

```js
const html = md.render(src)
```
<pre><code class="language-js"><span class="hljs-keyword">const</span> html = md.render(src)
</code></pre>

Add a language after the opening fence and the converter applies syntax highlighting, wrapping tokens in spans with a language-js class on the <code> element. Pair it with a highlight stylesheet and the code is colourised.

A README to a full HTML document

# My Project

A short description and a [link](https://example.com).
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>My Project</title></head>
<body>
<h1>My Project</h1>
<p>A short description and a <a href="https://example.com">link</a>.</p>
</body>
</html>

Switch the output to Full document and the converter wraps the rendered HTML in a complete page with a <head> and charset — a standalone .html file you can open in any browser or download directly.

How to Convert Markdown to HTML

  1. 1

    Type or paste your Markdown

    Drop your Markdown — a README, release notes, an issue body — into the input pane. Full GitHub Flavored Markdown is supported: tables, task lists, strikethrough, autolinks, and fenced code blocks. The live preview and HTML output update as you type, all in your browser.

  2. 2

    Choose an output format

    Pick HTML fragment for pasting into a template or CMS, Full document for a standalone .html page, or Email inline for inline-styled HTML that survives Outlook. Add language tags to code fences for syntax highlighting, and use the Custom CSS panel to style the preview.

  3. 3

    Copy or download

    Click Copy to grab the HTML, or Download to save it as a file. To reverse the conversion, switch to the HTML → Markdown tab and paste your HTML to get clean Markdown back.

Common Pitfalls

Unescaped HTML Swallowed in Prose

Markdown lets raw HTML through, so an angle bracket you meant as text — like writing about a <Component> or a generic List<T> — is parsed as an HTML tag and disappears from the output. Escape the bracket with a backslash or an HTML entity, or wrap the text in a code span so it is rendered literally.

✗ Wrong
Use the <Header> component to wrap pages.
<!-- <Header> is parsed as a tag and vanishes -->
✓ Correct
Use the `<Header>` component to wrap pages.
<!-- backticks keep it literal: renders <Header> -->

Misaligned or Malformed Table Pipes

A GFM table needs a header row, a delimiter row of dashes, and at least one pipe per row. Forgetting the delimiter row, or having a different number of columns than the header, breaks the table — it falls back to a plain paragraph of pipes. The cells need not line up visually, but every row must have the same number of columns.

✗ Wrong
| Name | Role |
| Alice | Admin |
<!-- no |---|---| delimiter row: not a table -->
✓ Correct
| Name | Role |
| ---- | ---- |
| Alice | Admin |
<!-- delimiter row present: renders a table -->

Code Fence Without a Language

A fenced code block with no language info string renders as a <pre><code> block with no language class, so it gets no syntax highlighting. The code still appears, just monochrome. Add the language immediately after the opening backticks to enable highlighting; a space between the backticks and the name disables it.

✗ Wrong
```
const x = 1
```
<!-- no language → no highlighting -->
✓ Correct
```js
const x = 1
```
<!-- language-js → highlighted -->

Using a Fragment Where a Full Document Is Needed

Copying the HTML fragment output and saving it directly as a .html file produces a page with no doctype, no charset, and no <html>/<head>/<body>. Browsers will often render it anyway, but quirks mode and missing charset can break accented characters and layout. When the HTML must stand alone, switch to the Full document format.

✗ Wrong
<h1>Title</h1>
<p>Saved as page.html — no doctype, no charset.</p>
✓ Correct
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><title>Title</title></head>
<body><h1>Title</h1><p>Complete, standalone page.</p></body></html>

Common Use Cases

Publish into a static site or CMS
Write your content in Markdown, convert to an HTML fragment, and paste it into a static-site template or a CMS rich-text field. You get clean semantic markup — headings, lists, tables — without the page wrapper getting in the way.
Preview a README before you push
Paste your README.md and watch the live preview render it with full GFM — tables, task lists, fenced code — so you catch a broken table or a missing code fence before the commit, not after GitHub shows it to the world.
Turn notes into a shareable web page
Meeting notes, a design doc, or a draft written in Markdown becomes a complete HTML page in one click. Choose Full document, download the .html file, and you have something you can open in any browser or host anywhere.
Build email-safe inline-styled HTML
Email clients strip <style> blocks, so write your message in Markdown and export the Email inline format, which moves CSS onto each element as a style attribute. The result renders correctly in Outlook and other clients that ignore document-level styles.
Convert a .md file to a downloadable .html
Need an offline, self-contained HTML version of a Markdown document? Paste it, pick Full document, and Download — you get a standalone .html file with a proper doctype and charset, no build tool or command line required.
Embed rendered docs in an app
Generating documentation, changelogs, or help content from Markdown stored in your repo? Use this tool to see exactly what HTML a given Markdown source produces, so you can match your app's renderer and style the output to fit.

Technical Details

CommonMark vs GitHub Flavored Markdown
CommonMark is the strict, unambiguous Markdown specification that defines exactly how headings, emphasis, lists, links, and code blocks parse. GitHub Flavored Markdown (GFM) is a strict superset: it keeps everything CommonMark defines and adds four extensions — pipe tables, task list items (`- [x]`), strikethrough (`~~text~~`), and autolinked bare URLs. Because GFM only adds features, any valid CommonMark document is also valid GFM. This converter implements the GFM superset, so documents written for either grammar render correctly.
XSS-Safe Sandboxed Rendering
Markdown intentionally allows embedded raw HTML, which means a Markdown document can contain a <script> tag or an event handler like onerror. The live preview defends against this by rendering inside an <iframe sandbox=""> with scripting disabled, so active content in your input cannot execute while you preview it — important when you are converting Markdown from an untrusted source. The serialised HTML the tool outputs is the faithful rendering of your input; if you plan to publish HTML derived from untrusted Markdown, run it through a sanitiser such as DOMPurify on your server before serving it.
Email HTML Compatibility
HTML email is rendered by a patchwork of engines with notoriously limited CSS support. Outlook on Windows uses Word's rendering engine and ignores <style> blocks in the document head, so any class-based styling silently disappears; the reliable approach is inline style attributes on each element, which is what the Email inline output produces. Images are another trap: many clients block remote images until the recipient opts in, so embedding small images as data URIs renders them immediately, while large remote images may not appear at all. Keep the markup simple and test across your target clients.
Synchronous In-Browser Highlighting
When a fenced code block carries a language info string (```js), the converter runs a synchronous highlighter over its contents, tokenising the source and wrapping each token in a <span> with a class such as hljs-keyword or hljs-string, plus a language-js class on the <code> element. The highlighting is structural only — it adds classes, not colours — so the destination page needs a matching highlight stylesheet to render the palette. Because it runs synchronously in the browser, the highlighted HTML appears the instant you type, with no network call.

Best Practices

Choose the Output Format for the Destination
Match the format to where the HTML is going. A CMS field or template already has a page wrapper, so paste an HTML fragment. A file you want to open directly in a browser needs a Full document with doctype and charset. An email needs Email inline so the styles survive clients that strip <style> blocks. Pasting the wrong shape is the most common avoidable mistake.
Always Tag Code Fences with a Language
Write the language right after the opening backticks — ```js, ```python, ```sql — with no space, so the converter can highlight the block and add the correct language class. A bare fence produces unstyled, unhighlighted code. Use a language the highlighter recognises; an unknown or misspelled name falls back to plain text.
Sanitise Before Publishing Untrusted Markdown
The preview is sandboxed, but the HTML the tool emits is a faithful rendering — including any raw HTML or <script> in the input. If that Markdown came from users or another untrusted source and you intend to serve the result to other people, run the HTML through a sanitiser such as DOMPurify on your server first. The sandbox protects you while converting, not your visitors after you publish.
Keep Email HTML Simple and Inline
For email, prefer the Email inline format, keep your layout simple, and avoid CSS features that Outlook and other clients drop. Inline small images as data URIs so they render even when remote images are blocked, and always send yourself a test before a wider send — email rendering is the least forgiving target HTML has.
Escape Literal HTML Characters in Text
If you want a literal < or & to appear as text rather than be interpreted as a tag or entity, escape it with a backslash (\<) or an HTML entity (<). Markdown passes raw HTML through, so an unescaped <example> in prose can be swallowed as an unknown tag and vanish from the rendered output.

Frequently Asked Questions

Does it support GitHub Flavored Markdown (GFM)?
Yes. The converter renders the full GitHub Flavored Markdown superset on top of CommonMark: pipe tables, task lists (`- [x]` / `- [ ]`), strikethrough with `~~text~~`, autolinked URLs, and fenced code blocks with language info strings. That means a README, an issue body, or a wiki page written for GitHub renders here the same way GitHub renders it, so your README preview matches reality before you push. Plain CommonMark documents work too — GFM only adds features, it never removes them.
How do I get email-safe inline-styled HTML?
Choose the Email inline output tab. Most email clients — Outlook in particular — strip or ignore <style> blocks in the document head, so any CSS you put there is discarded and your formatting collapses. The Email inline format solves this by moving the styles directly onto each element as a style attribute (for example <h1 style="font-size:2em;margin:0 0 16px">), which clients honour. Paste the result straight into your email template or ESP. Keep images small and prefer data URIs or absolute https URLs, since many clients block remote images by default.
What's the difference between an HTML fragment and a full document?
An HTML fragment is just the rendered body markup — the <h1>, <p>, <ul>, <table> and so on — with no surrounding page. Use it when you are pasting into something that already has its own <html>, <head>, and <body>, such as a CMS rich-text field, a static-site template, or a React component. A full document wraps that same markup in a complete page with a <head>, a charset declaration, and a <title>, so it stands alone — open it in a browser or save it as a .html file. Picking the wrong one is a common mistake: a fragment dropped into a browser tab renders, but without a doctype or charset it can misbehave.
Is the rendered HTML XSS-safe to preview?
The live preview is rendered inside a sandboxed <iframe> with scripts disabled, so even if your Markdown contains raw <script> tags or an onerror handler, nothing executes while you preview. This matters because Markdown permits embedded HTML by design, and converting untrusted Markdown can otherwise inject active content. The sandbox protects you, the person doing the conversion. Note that the HTML string the tool outputs is the faithful rendering of your input — if that input came from an untrusted source and you intend to publish the result, sanitise it on your server (for example with DOMPurify) before serving it to other users.
Can I add my own CSS to the preview?
Yes. Open the Custom CSS panel and type any rules you like — for instance h1 { color: #0969da; } or table { border-collapse: collapse; }. The styles are injected into the sandboxed preview iframe so you see your Markdown rendered with your own look immediately, which is handy for matching a site's typography or checking how a README will appear with GitHub-style CSS. The custom CSS affects only the live preview; the HTML you copy from the output tabs is unstyled fragment or document markup unless you choose the Email inline format.
Are my files or text uploaded to a server?
No. The conversion runs entirely in your browser with JavaScript — your Markdown is parsed and serialised to HTML locally and never transmitted, stored, or logged. You can confirm this by opening your browser's Network tab: converting text triggers zero network requests. That makes the tool safe for unpublished documentation, internal READMEs, release notes under embargo, and any content you are not ready to share. There is no upload step and no file-size limit beyond what your browser can comfortably hold in memory.
Does it work offline?
Once the page has loaded, yes — the Markdown parser, the syntax highlighter, and the HTML serialiser all run in the browser with no server round-trip, so you can convert with your network disconnected. This is a direct consequence of the privacy-first design: because nothing is sent anywhere, there is nothing the tool needs the network for after the initial load. It is convenient on a plane, behind a restrictive firewall, or any time you simply do not want a document leaving your machine.
How do I convert a Markdown (.md) file to an HTML file?
Paste or open your Markdown in the input pane, choose the Full document output so the result is a standalone page, then click Download to save it as a .html file you can open in any browser. If you only need the body markup to drop into an existing template, choose HTML fragment instead and copy it. There is no separate upload — paste the contents of your .md file (or drag it in where supported) and the converted HTML is ready instantly, entirely in your browser.
Why isn't my code block highlighted?
Syntax highlighting only kicks in when you tell the converter which language a fenced code block is in. Write the language as an info string immediately after the opening triple backticks — ```js, ```python, ```sql — with no space. A bare ``` fence produces a <pre><code> block with no language class and therefore no colour. A misspelled or unsupported language name (```javscript) is treated as plain text too. Also remember that highlighting adds <span> classes like hljs-keyword; you need a matching highlight stylesheet on the destination page for the colours to actually appear.
Can I convert HTML back to Markdown?
Yes. Switch to the HTML → Markdown tab, or open the dedicated HTML to Markdown converter, paste your HTML, and get clean Markdown back — with options for ATX vs Setext headings and inline vs reference links. The two directions are complementary: use Markdown → HTML to publish or preview, and HTML → Markdown to bring existing web content into a Markdown-based workflow such as a static site or a docs repo. To tidy the HTML first, our HTML Formatter pretty-prints it.

Related Tools

View all tools →