Markdown to HTML Converter – Free Online MD to HTML & HTML to MD Tool

Markdown to HTML Converter

Convert Markdown to HTML and HTML to Markdown in real time. Live preview, GitHub-flavored syntax, code highlighting, table of contents, sanitization, themes, file upload, URL fetch & full export โ€” all client-side.

๐Ÿ“ Markdown โ†’ HTML ๐Ÿ”„ HTML โ†’ Markdown ๐Ÿ‘ Live Preview
Markdown input 0 words ยท 0 chars ยท 0 min read
๐ŸŒ URL ๐Ÿ“‹ Paste ๐Ÿ“„ Sample ๐Ÿ—‘ Clear
HTML output 0 chars ยท 0 lines
๐Ÿ–ผ Rendered ๐Ÿ’ป Code
๐Ÿ“‹ Copy ๐Ÿ“‹ Copy rich โฌ‡ Download ๐Ÿ–จ Print/PDF ๐Ÿ”— Share
โ–ถ Convert (Ctrl+Enter) โ†ป Swap I/O โ†บ Reset all
Words
0
Characters
0
Lines
0
Headings
0
Links
Reading time
0 min
History (last 10)

How to Use the Markdown to HTML Converter

  1. Pick a mode: Markdown โ†’ HTML, HTML โ†’ Markdown, or Live Preview (side-by-side editor).
  2. Type or paste your content, upload a file (.md, .markdown, .html), fetch from a URL, or load a sample.
  3. Toggle options โ€” pick a theme (GitHub, Clean, Bootstrap, Dark, Minimal), enable GFM tables, syntax highlighting, HTML sanitization, auto-TOC, emoji shortcodes.
  4. Switch between Rendered view and raw Code view of the output.
  5. Copy as plain text or rich (paste straight into Word/Docs), download as .html or .md, print to PDF, or share via URL.
  6. Use Swap I/O to round-trip โ€” turn output into input and back to verify accuracy.

What is Markdown?

Markdown is a lightweight markup language created by John Gruber in 2004 that lets you write formatted text using plain-text syntax. It's the de-facto standard for README files on GitHub/GitLab, documentation sites, static blogs (Jekyll, Hugo, 11ty), Notion-style note-taking apps, Reddit/Discord/Stack Overflow comments, and AI chat outputs.

This converter uses marked.js โ€” the most widely-deployed JavaScript Markdown parser โ€” with full GitHub Flavored Markdown (GFM) support: tables, task lists, autolinks, strikethrough, fenced code blocks, and more. For the reverse direction (HTML โ†’ Markdown) it uses turndown, the industry standard. Code highlighting is powered by highlight.js (170+ languages), and HTML output is optionally sanitized through DOMPurify to strip dangerous tags.

Everything runs 100% in your browser โ€” no upload, no signup, no logs.

Common Use Cases

๐Ÿ“ Blog posts & articlesWrite in Markdown, paste polished HTML into WordPress, Medium or Ghost.
๐Ÿ“– DocumentationConvert README files into web-ready HTML with TOC and syntax highlighting.
๐Ÿ“ง Email newslettersWrite in Markdown, paste rich into Mailchimp/Substack composer.
๐ŸŽ“ Note-takingConvert Obsidian/Notion notes into shareable HTML pages.
๐Ÿ’ผ Reports & proposalsWrite in plain text, deliver as styled HTML or PDF.
๐ŸŒ Static sitesAuthor content for Hugo/Jekyll/Astro and preview before commit.
๐Ÿค– ChatGPT/Claude outputConvert AI-generated Markdown into formatted HTML.
๐Ÿ“š GitHub READMEsTest how your README renders before pushing.
๐Ÿ”„ HTML to MarkdownPull existing HTML content back into clean editable Markdown.
๐Ÿ“‹ Cheat sheets & wikisBuild structured docs faster with tables, lists and code blocks.

Why Choose Our Markdown Converter?

โšก Industry-grade enginesmarked.js + turndown + DOMPurify + highlight.js.
๐Ÿ”’ 100% privateRuns entirely in your browser. No upload.
๐Ÿ‘ Live previewSee changes as you type โ€” real-time rendering.
๐Ÿ”„ BidirectionalMarkdown โ†” HTML โ€” both directions in one tool.
๐ŸŽจ 5 themesGitHub, Clean, Bootstrap, Dark, Minimal โ€” picked one click.
๐Ÿ“Š GFM supportTables, task lists, strikethrough, autolinks, fenced code.
๐ŸŒˆ Syntax highlighting170+ languages via highlight.js.
๐Ÿ“š Auto Table of ContentsOne toggle adds a clickable TOC.
๐Ÿ›ก HTML sanitizationDOMPurify strips XSS-risky tags optionally.
๐Ÿ“‹ Copy rich textPaste straight into Word, Google Docs, Outlook.
๐Ÿ–จ Print to PDFOne click, fully styled PDF export.
๐Ÿ“‚ File upload + URL fetchLoad .md, .markdown, .html or fetch any URL.
๐Ÿ“Š Live statsWords, chars, lines, headings, links, reading time.
๐Ÿ”— Share linkURL that restores content + settings.
๐Ÿ“œ HistoryLast 10 conversions in localStorage.
๐ŸŒ™ Dark modePersisted across sessions.
๐Ÿ–ฅ FullscreenDistraction-free writing.
โ†• Sync scrollEditor and preview scroll together.
โ™พ Free & unlimitedNo quotas, no signup, no ads in the workflow.

Frequently Asked Questions

Which Markdown flavor does this support?

CommonMark plus GitHub Flavored Markdown (GFM) โ€” tables, task lists (- [x]), strikethrough (~~text~~), autolinks, fenced code blocks with language hints, footnotes, definition lists. It's the same dialect used by GitHub, GitLab, Bitbucket and most modern static-site generators.

What's the difference between "Copy" and "Copy rich"?

Copy copies the raw HTML source code (good for pasting into a CMS or HTML file). Copy rich copies the rendered output as formatted text โ€” paste into Word, Google Docs, Outlook, Notion or any rich-text editor and formatting is preserved.

Is the HTML output safe to embed on my site?

If the Sanitize HTML option is on (default), output is run through DOMPurify which strips <script> tags, event handlers (onclick etc.), and javascript: URLs. Even with sanitization off, our tool itself doesn't add anything malicious โ€” but be cautious converting Markdown from untrusted sources with sanitization disabled.

How accurate is the HTML โ†’ Markdown conversion?

Excellent for most common HTML โ€” headings, lists, links, tables, code blocks, bold/italic, blockquotes. Less perfect on heavily nested or visually-styled HTML (complex CSS layouts, custom components). The conversion is best-effort and produces clean readable Markdown.

Does it support math (LaTeX)?

Inline LaTeX ($x^2$) and block LaTeX ($$\sum_{i=1}^n$$) render as plain text โ€” to enable rendered math, copy the HTML output and add MathJax or KaTeX to your destination page.

Does it support Mermaid diagrams?

Mermaid code blocks are kept intact in the HTML output. Add the Mermaid script to your destination page to render them.

What about embedded HTML inside my Markdown?

marked.js passes raw HTML through. If Sanitize is on, dangerous tags get stripped. Otherwise your HTML is preserved as-is.

What's the file size limit?

Soft limit of about 5 MB. Beyond that, browsers begin to struggle with live rendering.

Is my content uploaded anywhere?

No. Everything is processed locally in your browser. The only network call is the optional URL-fetch feature.

\n'; } var blob = new Blob([content], { type: ext === 'html' ? 'text/html' : 'text/markdown' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'document.' + ext; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(function() { URL.revokeObjectURL(url); }, 100); toast('Downloaded', 'ok'); return; } if (act === 'print') { if (!els.rendered.innerHTML.trim()) { toast('Nothing to print', 'err'); return; } var w = window.open('', '_blank'); w.document.write('Print' + els.rendered.innerHTML + ''); w.document.close(); setTimeout(function() { w.print(); }, 500); return; } if (act === 'share') { try { var d = { i: els.input.value, m: state.mode, t: state.theme }; var enc = btoa(unescape(encodeURIComponent(JSON.stringify(d)))); if (enc.length > 6000) { toast('Content too large to share', 'err'); return; } var link = location.origin + location.pathname + '#md=' + enc; navigator.clipboard.writeText(link).then(function() { toast('Share link copied', 'ok'); }).catch(function() { prompt('Copy:', link); }); } catch (e) { toast('Share failed', 'err'); } return; } if (act === 'swap') { var i = els.input.value, o = els.output.value; if (!o) { toast('Nothing to swap', 'err'); return; } els.input.value = o; setActiveMode(state.mode === 'm2h' ? 'h2m' : state.mode === 'h2m' ? 'm2h' : 'm2h'); toast('Swapped I/O', 'ok'); return; } if (act === 'paste') { navigator.clipboard.readText().then(function(t) { els.input.value = t; autoRun(); toast('Pasted', 'ok'); }).catch(function() { toast('Paste blocked โ€” use Ctrl+V', 'err'); }); return; } if (act === 'clear') { els.input.value = ''; els.output.value = ''; els.rendered.innerHTML = ''; updateStats(''); updateOutMeta(); setStatus(''); return; } if (act === 'reset') { els.input.value = ''; els.output.value = ''; els.rendered.innerHTML = ''; setActiveMode('m2h'); els.theme.value = 'github'; applyTheme('github'); updateStats(''); updateOutMeta(); setStatus(''); toast('Reset', 'ok'); return; } if (act === 'sample') { els.input.value = state.mode === 'h2m' ? '

Sample HTML Document

\n

This is a sample with various elements.

\n
    \n
  • List item one
  • \n
  • List item two with a link
  • \n
\n
A blockquote example.
\n
function hello() {\n  console.log("world");\n}
\n\n\n\n\n
NameScore
Alice95
Bob87
' : '# Welcome to Markdown\n\n**Bold text**, *italic text*, and ~~strikethrough~~.\n\n## Features\n\n- โœ… Lists with task items\n- [x] Completed task\n- [ ] Pending task\n- ๐Ÿš€ Emojis: :rocket: :sparkles: :tada:\n\n## Code blocks\n\nInline `code` works, and so do fenced blocks:\n\n```javascript\nfunction greet(name) {\n return `Hello, ${name}!`;\n}\nconsole.log(greet("world"));\n```\n\n## Tables\n\n| Name | Score | Status |\n|-------|-------|----------|\n| Alice | 95 | โœ… Passed |\n| Bob | 87 | โœ… Passed |\n| Carol | 62 | โŒ Failed |\n\n## Links & images\n\nVisit [our website](https://example.com) or try this image:\n\n![Sample](https://via.placeholder.com/400x200)\n\n## Blockquotes\n\n> "The best way to predict the future is to invent it." \n> โ€” Alan Kay\n\n## Horizontal rule\n\n---\n\nThanks for trying the converter! :coffee:'; autoRun(); toast('Sample loaded', 'ok'); return; } if (act === 'url') { var url = prompt('Enter URL of .md or .html file:'); if (!url) return; setStatus('Fetching ' + url + 'โ€ฆ', 'info'); fetch('https://api.allorigins.win/raw?url=' + encodeURIComponent(url)).then(function(r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }).then(function(t) { els.input.value = t; if (/\.html?$/i.test(url)) setActiveMode('h2m'); else setActiveMode('m2h'); autoRun(); toast('Fetched', 'ok'); }).catch(function(e) { setStatus('Fetch failed: ' + e.message, 'err'); toast('Fetch failed', 'err'); }); return; } }var queued = window.pctMd._q || []; window.pctMd = { setMode: setActiveMode, setOutTab: setOutTab, act: handleAction, restoreHistory: function(i) { var h = state.history[i]; els.input.value = h.in; setActiveMode(h.mode); autoRun(); els.historyDrawer.classList.remove('pct-md-open'); toast('Restored', 'ok'); }, deleteHistory: function(i) { state.history.splice(i, 1); try { localStorage.setItem('pct-md-history', JSON.stringify(state.history)); } catch (e) {} renderHistory(); } }; queued.forEach(function(q) { var name = q[0], args = q[1]; if (window.pctMd[name]) window.pctMd[name].apply(window.pctMd, args); });function pushHistory(inp, out) { if (!inp || !out) return; if (state.history[0] && state.history[0].in === inp.slice(0, 200)) return; state.history.unshift({ ts: Date.now(), in: inp.slice(0, 20000), out: out.slice(0, 20000), mode: state.mode }); if (state.history.length > 10) state.history = state.history.slice(0, 10); try { localStorage.setItem('pct-md-history', JSON.stringify(state.history)); } catch (e) {} renderHistory(); } function loadHistory() { try { state.history = JSON.parse(localStorage.getItem('pct-md-history') || '[]'); } catch (e) { state.history = []; } renderHistory(); } function renderHistory() { if (!state.history.length) { els.historyList.innerHTML = '

No history yet.

'; return; } var h = ''; state.history.forEach(function(it, i) { var d = new Date(it.ts); h += '
' + it.mode.toUpperCase() + ' ยท ' + d.toLocaleString() + 'ร—
' + escHTML(it.in.slice(0, 60)) + 'โ€ฆ
'; }); els.historyList.innerHTML = h; }els.fileInput.addEventListener('change', function(e) { var f = e.target.files[0]; if (!f) return; if (f.size > 5242880) { toast('File too large (max 5 MB)', 'err'); return; } var ext = (f.name.split('.').pop() || '').toLowerCase(); if (/^(html?|htm)$/.test(ext)) setActiveMode('h2m'); else setActiveMode('m2h'); var rd = new FileReader(); rd.onload = function(ev) { els.input.value = ev.target.result; autoRun(); toast('Loaded ' + f.name, 'ok'); }; rd.readAsText(f); e.target.value = ''; });els.input.addEventListener('input', autoRun); els.input.addEventListener('drop', function(e) { e.preventDefault(); var f = e.dataTransfer.files[0]; if (!f) return; if (f.size > 5242880) { toast('File too large', 'err'); return; } var rd = new FileReader(); rd.onload = function(ev) { els.input.value = ev.target.result; autoRun(); toast('Dropped ' + f.name, 'ok'); }; rd.readAsText(f); }); els.input.addEventListener('dragover', function(e) { e.preventDefault(); }); [els.gfm, els.breaks, els.hi, els.sanitize, els.toc, els.linkify, els.emoji].forEach(function(cb) { cb.addEventListener('change', autoRun); }); els.theme.addEventListener('change', function() { applyTheme(els.theme.value); }); els.wrap.addEventListener('change', function() { root.classList.toggle('pct-md-wrap-on', els.wrap.checked); }); els.sync.addEventListener('change', function() {}); els.input.addEventListener('scroll', function() { if (!els.sync.checked) return; var ratio = els.input.scrollTop / (els.input.scrollHeight - els.input.clientHeight); if (state.outTab === 'rendered') els.rendered.scrollTop = ratio * (els.rendered.scrollHeight - els.rendered.clientHeight); });document.addEventListener('click', function(e) { /* inline onclick handles it */ }); document.addEventListener('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); run(); } if (e.key === 'Escape' && root.classList.contains('pct-md-full')) { root.classList.remove('pct-md-full'); } }); root.addEventListener('keydown', function(e) { if ((e.key === 'Enter' || e.key === ' ') && e.target.getAttribute && e.target.getAttribute('role') === 'button') { e.preventDefault(); e.target.click(); } });(function() { if (location.hash.indexOf('#md=') === 0) { try { var d = JSON.parse(decodeURIComponent(escape(atob(location.hash.substring(4))))); els.input.value = d.i || ''; setActiveMode(d.m || 'm2h'); if (d.t) { els.theme.value = d.t; applyTheme(d.t); } autoRun(); } catch (e) {} } })();try { if (localStorage.getItem('pct-md-dark') === '1') root.classList.add('pct-md-dark'); } catch (e) {} loadHistory(); updateStats(''); updateOutMeta(); } })();
Scroll to Top