Back to Blog

Converting Markdown to HTML — Why and How

Markdown was created in 2004 by John Gruber as an easy way to write text that converts to HTML. Every heading, list and link you type in Markdown has a direct HTML equivalent. Understanding how that conversion works helps you publish content on the web, build documentation sites, send formatted emails and avoid surprises with styling and security.

When do you need Markdown as HTML?

  • Publishing on the web. Browsers display HTML, not Markdown. Blogs, CMSs and documentation sites convert Markdown to HTML before serving it.
  • Pasting into a CMS or website builder that accepts HTML but not Markdown (WordPress Custom HTML blocks, Shopify pages, Webflow embeds).
  • Email newsletters — email clients render HTML.
  • Embedding content in an app — for example rendering user comments or help articles.
  • Custom styling — once you have HTML you can add classes, IDs and CSS.

How Markdown maps to HTML

Markdown HTML
# Heading 1 <h1>Heading 1</h1>
## Heading 2 <h2>Heading 2</h2>
**bold** <strong>bold</strong>
*italic* <em>italic</em>
[text](https://example.com) <a href="https://example.com">text</a>
![alt](image.png) <img src="image.png" alt="alt">
- item <ul><li>item</li></ul>
1. item <ol><li>item</li></ol>
> quote <blockquote><p>quote</p></blockquote>
`code` <code>code</code>
fenced code block <pre><code class="language-js">…</code></pre>
--- <hr>

A complete example — this Markdown:

## Getting started

Install the package with **npm**:

    npm install my-lib

See the [docs](https://example.com/docs) for more.

becomes:

<h2>Getting started</h2>
<p>Install the package with <strong>npm</strong>:</p>
<pre><code>npm install my-lib
</code></pre>
<p>See the <a href="https://example.com/docs">docs</a> for more.</p>

CommonMark vs GitHub Flavored Markdown

The original Markdown description left many edge cases undefined, so different converters produced different HTML. CommonMark is a strict specification that fixes this. GitHub Flavored Markdown (GFM) is CommonMark plus extensions: tables, task lists (- [ ]), strikethrough (~~text~~) and automatic links. Most modern converters, including MarkdownNote, follow GFM, so a document that renders correctly on GitHub converts the same way.

Method 1: Online converter

The MarkdownNote Markdown to HTML converter converts as you type:

  1. Paste Markdown or upload a .md file.
  2. Choose options: Full HTML document (adds <html>, <head> and basic styles), Minify output, Syntax highlight code.
  3. Copy the HTML or download it as an .html file.

Everything runs in your browser, so it is safe for private content.

Method 2: JavaScript (Node.js or browser)

marked is a fast, popular Markdown parser:

import { marked } from "marked";

const html = marked.parse("# Hello\n\nThis is **Markdown**.");
console.log(html);
// <h1>Hello</h1>
// <p>This is <strong>Markdown</strong>.</p>

Other good options are markdown-it (very extensible with plugins) and remark/rehype (part of the unified ecosystem, used by many static site generators).

Method 3: Python

import markdown

html = markdown.markdown(
    "# Hello\n\n| a | b |\n|---|---|\n| 1 | 2 |",
    extensions=["tables", "fenced_code"],
)
print(html)

Method 4: Pandoc

# HTML fragment
pandoc README.md -o readme.html

# standalone page with <head> and a title
pandoc README.md -s -o readme.html --metadata title="README"

Method 5: Static site generators

If you are building a whole website from Markdown files, a static site generator does the conversion, layout and navigation for you: Hugo, Jekyll, Eleventy, Astro, Docusaurus, MkDocs and VitePress are all popular choices.

Styling the HTML output

Converted HTML is unstyled. Add a stylesheet that targets the plain elements:

body { max-width: 720px; margin: 2rem auto; font: 16px/1.7 system-ui, sans-serif; color: #1f2937; }
h1, h2, h3 { line-height: 1.3; }
pre { background: #f3f4f6; padding: 1rem; border-radius: 8px; overflow-x: auto; }
table { border-collapse: collapse; }
th, td { border: 1px solid #e5e7eb; padding: .5rem .75rem; }

For HTML emails, styles in a <style> tag are not supported everywhere — use an inliner tool so that each element gets inline style attributes.

Security: sanitize user content

Markdown allows raw HTML, so a user could write <img src=x onerror="alert(1)">. If you convert Markdown written by other people (comments, forum posts, user profiles), always sanitize the resulting HTML, for example with DOMPurify in JavaScript or bleach/nh3 in Python. For your own content this is not necessary.

Converting HTML back to Markdown

Migrating a blog or documentation from a CMS to Markdown? Use the HTML to Markdown converter — it supports tables (GFM), lets you choose heading and bullet styles, and runs locally in your browser.

Heading IDs and a table of contents

Many converters add an id to every heading so you can link to sections directly:

<h2 id="getting-started">Getting started</h2>

That makes links like page.html#getting-started possible and lets you build a table of contents. GitHub does this automatically for READMEs. With marked you can add IDs using an extension such as marked-gfm-heading-id; Pandoc adds them by default and generates a table of contents with --toc.

Syntax highlighting in the output

Fenced code blocks with a language (```python) are converted to <pre><code class="language-python">. The HTML on its own is not colored — you need a highlighter:

  • highlight.js or Prism in the browser: include the library and a theme stylesheet, and code blocks are colored on page load.
  • Shiki at build time: produces pre-colored HTML with no JavaScript needed in the browser.
  • In the Markdown to HTML converter, enable Syntax highlight code to get highlighted markup in the output.

Automating conversion in a project

If your documentation lives in a repository, convert it automatically instead of by hand:

// build-docs.mjs — convert every .md file in /docs to .html
import { readdir, readFile, writeFile } from "node:fs/promises";
import { marked } from "marked";

for (const file of await readdir("docs")) {
  if (!file.endsWith(".md")) continue;
  const md = await readFile(`docs/${file}`, "utf8");
  const body = marked.parse(md);
  const page = `<!doctype html><meta charset="utf-8"><link rel="stylesheet" href="style.css">${body}`;
  await writeFile(`docs/${file.replace(/\.md$/, ".html")}`, page);
}

Run it with node build-docs.mjs, or add it as a step in your CI pipeline so the HTML is regenerated on every commit.

Frequently asked questions

Does converting Markdown to HTML affect SEO?

Search engines only see the final HTML. Markdown simply gives you clean, semantic HTML — proper headings, lists and links — which is good for SEO.

Why does my HTML have no styles?

Markdown converters output structure, not design. Enable Full HTML document in the converter for basic styles, or add your own CSS.

Can I write HTML directly inside Markdown?

Yes. Most renderers pass raw HTML through unchanged, which is useful for things Markdown cannot express, such as <details> blocks or merged table cells.

Convert Markdown to HTML instantly

Clean, semantic HTML as you type — fragment or full page, minified or pretty.

Open MD to HTML converter