Type **done** in a GitHub comment, and it appears as done. Add # to a README line, and it becomes a heading. Paste the same text elsewhere, and a table may collapse into pipes and dashes. These moments share one idea; understanding it makes them feel predictable.
Markdown is plain text that programs convert into HTML (HyperText Markup Language), which browsers display. This article explains why Markdown exists, how renderers process it, why its meaning varies by context, and when it’s unsuitable.
A Syntax and a Tool
Markdown is both a plain-text formatting syntax and a Perl software tool that converts it to HTML. John Gruber developed it with Aaron Swartz in 2004, according to the CommonMark project’s history. The original script’s final release, Markdown 1.0.1, dates to 17 December 2004.
Today the word mostly means the syntax, and dozens of other programs read the same conventions.
Here is a short Markdown document:
## Release notes
The import job is **faster** and skips *empty* rows.
* Fixed the date parser.
* Added a `--dry-run` flag.
Read the [full changelog][changelog].
[changelog]: https://example.com/changelogEven if you’ve never seen Markdown, you can read it, and Gruber designed it so you could.
Why Markdown Exists
Before Markdown, web writing meant hand-coding HTML or using a rich text editor. HTML hides words in tags: bolding one word yields The import job is <strong>faster</strong>., while a list requires opening, item, and closing tags. Editors conceal tags but produce markup that’s hard to read, compare, or fix.
Gruber drew on familiar plain-text formatting. His syntax documentation identifies plain-text email as the main inspiration, where people used *emphasis* and dashes for lists before renderers supported them. Earlier text-to-HTML filters, including Setext, atx, Textile, and reStructuredText, also influenced it.
His strict goal: Markdown files should work as plain text, ready to publish without looking marked up. This explains most of Markdown’s choices.
A # heading and blank-line paragraph break should remain clear in the source, even without rendering.
How Markdown Works
A Markdown file is document source code: a parser builds its structure, and a renderer converts it to HTML. Since most tools combine both, the whole tool is often called a renderer. CommonMark implementations use two broad parsing passes, following the strategy the CommonMark spec describes:
- Blocks first. It divides text into blocks—headings, paragraphs, lists, quotes, and code—using blank lines, leading
#characters, list markers, and indentation to mark boundaries. - Inlines second. Within each block, it detects inline structures—emphasis, links, code, and images—marked by
*, backticks, and square brackets.
The two passes build a nested document tree of headings, paragraphs, and inline pieces, which the renderer writes as HTML. The pipeline looks like this:
Render the release notes above to get roughly this:
<h2>Release notes</h2>
<p>The import job is <strong>faster</strong> and skips <em>empty</em> rows.</p>
<ul>
<li>Fixed the date parser.</li>
<li>Added a <code>--dry-run</code> flag.</li>
</ul>
<p>Read the <a href="https://example.com/changelog">full changelog</a>.</p>The source’s final line, [changelog]: https://..., is omitted because the renderer treats it as a definition and uses it wherever [changelog] appears.
A recipe is a useful analogy: Markdown is the readable recipe card, the renderer is the cook, and HTML is the plated dish. Give two cooks the same card, and their dishes will look alike but differ in details.
Why Markdown Has Flavors
Gruber documented the syntax through prose and examples, not a formal grammar, leaving gaps—such as whether lists could follow paragraphs without a blank line or how many spaces nested them. Renderer authors answered differently.
The CommonMark project says Gruber’s description does not specify the syntax unambiguously. By 2014, dozens of implementations had diverged: a document could render differently on GitHub wiki and Pandoc.
Since 2014, CommonMark has provided a clear specification and self-checking test suite. Its latest version is 0.31.2, dated 28 January 2024.
Flavors add features to the shared core that the original lacked:
- GitHub Flavored Markdown (GFM). GitHub’s spec is a strict superset of CommonMark, adding tables, task lists (
- [ ]), strikethrough, bare-URL autolinks, and filtering risky raw HTML tags like<script>. - Site generator flavors. Hugo, this blog’s static site generator, uses Goldmark, which conforms to the CommonMark specification and supports GFM. Hugo also enables footnotes, definition lists, and typographic quotes by default.
- Tool-specific flavors. Note, chat, and documentation apps each support different subsets, often without specifying which.
So “this is Markdown” is closer to “this is English” than “this is Python 3.12”: the core is shared, and the dialect depends on context.
How Markdown Relates to HTML, Git, and Other Formats
Markdown makes more sense next to the formats around it.
- HTML. Markdown fronts HTML. Gruber says, HTML is a publishing format; Markdown is a writing format. If Markdown lacks a feature, you can write HTML directly in the file.
- Plain text and version control. Because Markdown is plain text, Git can diff it line by line. This makes it ideal for READMEs, changelogs, architecture decision records, documentation sites, and writing good technical docs, which often starts in a
.mdfile. - Other lightweight markup. reStructuredText and AsciiDoc solve the same problem, offering richer built-in structure, such as admonitions and cross-references, at the cost of more syntax to learn.
- The
text/markdownmedia type. RFC 7763, an IETF Request for Comments registeredtext/markdownin March 2016 and assigned the extensions.mdand.markdown. It describes Markdown as “a family of plain-text formatting syntaxes,” treating its flavors as part of the format. - Diagrams as text. Tools like Mermaid use the same idea: describe a diagram in a fenced plain-text code block, then let a renderer draw it.
Trade-offs and Limitations
Markdown prioritizes writing over layout, with predictable trade-offs.
- Portability is partial. CommonMark-only files travel well; tables, footnotes, and task lists rely on specific flavors, so some tools display raw pipes and brackets.
- Structure is shallow. Markdown supports headings, lists, quotes, code, links, and images, but lacks native warning boxes, figure captions, and section cross-references. Tools invent extensions, worsening portability.
- Whitespace carries meaning. Indentation can turn a paragraph into code, while a missing blank line can attach a list to it. These bugs appear only when rendered.
- Tables are painful. GFM works for three columns of short values; wide tables, multiline or merged cells need HTML or another format.
- Raw HTML is a security question. HTML in Markdown can let user-submitted content carry scripts, so GitHub filters some tags, and many comment systems sanitize or disable HTML.
For books with indexes and cross-references or strictly structured manuals, AsciiDoc or DocBook may work better. For READMEs, notes, blog posts, issue comments, and most documentation, Markdown’s limits rarely matter.
Common Misconceptions
“Markdown is one standard.” Markdown has multiple flavors. CommonMark defines the core, but note apps, chat tools, and static site generators may differ. If something renders strangely, check the tool’s flavor before assuming a typo.
“Markdown replaces HTML.” Gruber wrote that Markdown is not a replacement for HTML. It handles common cases simply; for anything else, use HTML.
“Pressing Enter starts a new line.” In CommonMark, a line break within a paragraph is usually rendered as a space. A blank line starts a new paragraph. To force a break without starting a paragraph, end the line with a backslash or two spaces.
Some apps treat Enter as a break, which helps explain the confusion.
“The .md file is the finished document.” It’s the source; what readers see depends on the renderer, its flavor, and site styles. The same file may render with different heading anchors, link targets, and code highlighting across sites.
The Model to Keep
Markdown uses plain-text conventions, inspired by email, that renderers convert to HTML. Its human-readable source suits repositories, comments, and docs. Renderers determine the output, and gaps in the original description caused inconsistencies. CommonMark standardized the core; flavors like GFM added requested features.
Think of it as a readable recipe another cook will interpret. Write for source readers, check rendering in the target tool, and use CommonMark when files must travel.
Next Steps
- Read Fundamentals of Technical Writing for how to structure the documents you’ll write in Markdown.
- Read Software Documentation Gaps for what happens when those documents never get written.
- Try Learn Mermaid to draw diagrams inside your Markdown files.
- Skim the CommonMark spec examples for any rule that has surprised you. Each one shows the input and the exact HTML it should produce.
References
- Daring Fireball: Markdown, John Gruber’s original project page and the 1.0.1 release.
- Daring Fireball: Markdown Syntax Documentation, the original syntax description and design philosophy.
- CommonMark, for the history of diverging implementations and the case for a specification.
- CommonMark Spec, the current specification and version history.
- GitHub Flavored Markdown Spec, version 0.29-gfm (2019-04-06), with its extensions to CommonMark.
- RFC 7763: The text/markdown Media Type, the IETF registration of
text/markdown. - Hugo: Configure markup, for Hugo’s default Goldmark renderer and its extensions.

Comments #