Skip to the tool
DevToolBench

Markdown to HTML Converter

Render a declared CommonMark subset to HTML.

0 chars

Inline HTML in your Markdown is escaped rather than passed through, so a pasted <script> comes out as text. The result above is the HTML source, shown as text — this page never renders it.

Blocks
0
Headings
0
Links
0
Characters
0

Everything runs in your browser. Nothing you type is sent to a server.

Found a bug in this tool? Report it.

Share this tool

What this tool does

This Markdown to HTML converter turns a document into HTML source you can read, copy and paste into a template. It parses a declared subset of CommonMark — no library, no build step, and no network call — and shows the result as text rather than rendering it, so what you see is exactly what you are copying.

The subset is the honest part of this page. Most converters advertise "Markdown" and leave you to find out which dialect they meant when a footnote comes out as a literal caret. Here is the whole list of what is handled:

  • ATX headings, # through ######, with optional closing hashes.
  • Paragraphs, with hard breaks from two trailing spaces or a trailing backslash.
  • Emphasis and strong emphasis with either asterisks or underscores, including all three at once.
  • Inline code with any number of backticks, and fenced code blocks with backticks or tildes.
  • Ordered and unordered lists, one level of nesting, with a start attribute when the first number is not one.
  • Blockquotes, with a marker required on every line.
  • Links and images, with optional titles, including nested brackets and parentheses.
  • Thematic breaks written as three or more dashes, asterisks or underscores.
  • GFM tables, behind a toggle, with per-column alignment.

How to use it

  1. Paste your Markdown on the left.
  2. Leave the table option on unless your text uses pipes for something else.
  3. Copy the HTML source, or download it as a file.

Why the HTML is escaped

CommonMark permits raw HTML in the source and says it should pass straight through. That is correct for a static site generator you run over your own files and wrong for a converter that anyone can paste anything into. So every <, >, &, " and ' in the text becomes a character reference, and a <script> you paste arrives on the other side as visible text.

The same reasoning applies to link destinations, and there escaping is not enough. javascript: in an href contains no special character at all — nothing to escape — so it is filtered by scheme instead: anything outside http, https, mailto, tel and ftp is replaced with #, and data: survives only when it points at an image. The HTML entity encoder covers the escaping half of that problem in more detail.

If you want the opposite behaviour, you want a library and a sanitiser, in that order: convert with raw HTML enabled, then run the output through an allowlist that strips event handlers and unknown elements. A converter alone has never been a security boundary.

The code fence and its language

A fenced block written as ```ts becomes <pre><code class="language-ts">, which is the class name every syntax highlighter on the market looks for. Nothing inside the fence is parsed: a heading, a list marker or an unmatched asterisk in your sample code arrives intact, which is the entire point of the fence and the most common reason to prefer it over indented code blocks.

Tildes work as an alternative fence, and they are worth knowing about for exactly one case: showing a backtick fence inside a code block. Open with ~~~ and the backticks are just characters.

Tables, and the rule that identifies them

A table is recognised only when the second line is a delimiter rule made of dashes and optional colons. Without it, a line full of pipes is a paragraph — which is what you want when the pipes are shell commands rather than columns. A colon on the left means left alignment, on the right means right, both means centre, neither means no align attribute at all. Short rows are padded with empty cells and extra cells are dropped, so a ragged table still produces valid markup rather than a row with a different column count. If you are writing the table rather than converting one, the Markdown table generator builds the pipes and the rule for you.

Frequently asked questions

What is the difference between CommonMark and GitHub Flavoured Markdown?

CommonMark is the specification that pinned down what the original Markdown left ambiguous — how many spaces indent a nested list, what happens to an unmatched asterisk, whether a list needs a blank line before it. GFM is CommonMark plus a handful of extensions GitHub needed: tables, task lists, strikethrough and automatic linking of bare URLs. Everything here is CommonMark except the table option, which is the GFM one.

Why is my inline HTML escaped instead of kept?

Because the converter cannot know where the output is going. CommonMark says raw HTML passes through untouched, which is right for a build step you control and wrong for a browser tool that people paste other people's text into. A pasted script tag comes out as visible text rather than as a script, and that trade is deliberate. If you need raw HTML preserved, use a library in your own pipeline with an allowlist sanitiser after it.

What does this converter deliberately not support?

Reference-style links and images, footnotes, definition lists, setext headings underlined with equals signs, HTML blocks, loose lists that wrap each item in a paragraph, and lazy continuation of a blockquote. Nesting beyond one level inside a list item is not tested and may surprise you. Every one of those is a real part of Markdown somewhere; none is common enough in the text people paste here to justify the parser it needs.

Does a javascript: link survive the conversion?

No. A destination whose scheme is not http, https, mailto, tel or ftp becomes a plain hash, and data: URLs are only kept when they are images. Escaping the text does nothing against that attack, because the payload is alphanumeric — it needs a separate rule, and this is it.

Is my Markdown uploaded anywhere?

No. The parser is a few hundred lines of JavaScript running in this tab. Nothing you paste is sent to a server, which matters when the document is an internal spec or a draft under embargo.

Related tools

Updated