TS-27: Markdown
Markdown is a lightweight human-editable markup language. It is widely used for
simple documentation such as README files, contribution guides, changelogs,
pull request descriptions, and code comments, and it is supported by many source
code hosting platforms, issue trackers, and chat tools.
For technical documentation that requires tables of contents, cross-references, included files, admonitions, or diagrams, AsciiDoc is RECOMMENDED instead. See TS-28: AsciiDoc.
This technical standard offers tips and best practices for writing Markdown. It recommends GitHub Flavored Markdown (GFM), a strict superset of the CommonMark specification, as the baseline dialect.
For a complete language reference, see the CommonMark Specification and the GitHub Flavored Markdown Specification.
Overview
Markdown is a lightweight markup language with a plain-text formatting syntax. Its design goal is to be readable as-is, without the formatting tags or instructions of a richer markup language, while still allowing the text to be converted to structured formats such as HTML.
Markdown is suited to short, relatively simple documents. For longer or more structured technical documentation, AsciiDoc is RECOMMENDED; see TS-28: AsciiDoc.
When to use Markdown
Markdown is a good choice for:
READMEfiles and other repository meta-documents.- Changelogs, pull request descriptions, and issue comments.
- Code comments and API documentation that is co-located with source code.
- Chat and messaging platforms that support Markdown input.
When not to use Markdown
Avoid Markdown when a document needs:
- A generated table of contents.
- File includes or modular content.
- Complex tables, cross-references, or admonitions.
- Embedded diagrams or conditional rendering.
Prefer AsciiDoc for these cases.
Flavors and specifications
There are many incompatible Markdown dialects. To maximize portability and predictable rendering, documents SHOULD target a single, well-specified dialect.
GitHub Flavored Markdown (GFM) is RECOMMENDED. GFM is a strict superset of the CommonMark specification, adding tables, strikethrough, task lists, and automatic linking of URLs.
Documents SHOULD be valid CommonMark at minimum. Features that are specific to GFM (tables, strikethrough, task lists) MAY be used where the target rendering platform supports GFM (which is not limited to GitHub.com).
Some platforms add their own extensions on top of GFM. GitHub, for example, supports callouts (see Callouts), which are not part of the GFM specification. Such extensions MAY be used where the target platform supports them, but authors SHOULD be aware that they are not portable and will degrade on other renderers.
Avoid dialects that are not backed by a formal specification, such as the original Markdown.pl implementation. Avoid proprietary extensions that are unlikely to be portable across renderers.
File extensions
Markdown files SHOULD use the .md extension.
The extensions .markdown, .mdown, and .mkd MAY be used, but .md is
preferred for consistency and broad tool support.
Files that contain only Markdown table data, or that are consumed by a specific tool, MAY use a tool-specific extension.
Headings
Headings SHOULD be written using ATX-style syntax - one to six number signs
(#) followed by a single space and the heading text.
# Level 1 heading ## Level 2 heading ### Level 3 heading
Setext-style headings (underlining text with = or -) SHOULD NOT be used.
They only support two levels, are harder to edit, and are less widely supported.
A single space MUST be placed between the number signs and the heading text. Some processors do not recognize a heading when the space is omitted.
A blank line SHOULD be placed before and after each heading. Without blank lines, some processors will not parse the heading correctly.
Heading levels MUST increase by single steps. Do not skip from a level 1 heading directly to a level 3 heading.
Paragraphs and line breaks
A paragraph is one or more consecutive lines of text separated from the surrounding content by a blank line.
Paragraphs SHOULD NOT be indented with spaces or tabs. Leading indentation of four or more spaces may be interpreted as a code block.
To insert a hard line break (<br>) within a paragraph, end a line with two or
more spaces, or use a backslash (\) at the end of the line. Hard line breaks
SHOULD be used sparingly. Prefer separate paragraphs or lists.
Note
Trailing whitespace is invisible in most editors. Configure your editor to highlight trailing whitespace, or use a linter, to avoid accidental hard line breaks.
Emphasis
Use underscores (_) for italics and double asterisks () for bold. Keeping
the two markers distinct makes the intent of a run of emphasis obvious in
source, where text and text** are easily confused at a glance.
_italic text_ **bold text** **_bold and italic text_**
Underscores in the middle of a word are not interpreted as emphasis by some
processors. Where emphasis must fall inside a word, use a single asterisk
(text) instead, which is reliable in all positions.
For GFM, strikethrough is written using two tildes (~~):
~~struck-through text~~
Emphasis SHOULD be applied to words or short phrases, not to entire paragraphs. Do not nest emphasis unnecessarily.
For guidance on using emphasis appropriately in technical writing, see TS-26: Technical Writing Style Guide.
Lists
Unordered lists use a single marker — the hyphen (-) — followed by a single
space. Do not mix markers (-, *, +) within the same list.
- First item - Second item - Third item
Ordered lists use a number followed by a period and either one or two spaces:
1. First item 2. Second item 3. Third item
Two spaces are RECOMMENDED where list items carry continuation paragraphs or nested blocks. It puts the content at a four-space indent, matching the four-space nesting indent recommended below, so every continuation in the document lines up on the same column:
1. First item.
Continuation paragraph, aligned with the item text.
- A nested item, at the same indent.Note
CommonMark does not require the numbers in an ordered list to be sequential, but they SHOULD be sequential in source for readability. The rendered output is always sequential.
Nested lists are created by indenting child items. Indentation of nested list items MUST be consistent. Four spaces of indentation per nesting level is RECOMMENDED for portability and readability.
To include multiple paragraphs or other block elements in a single list item, indent the continuation lines to align the text with the first line (ie. the indentation size is the number of characters in the list marker plus its trailing space). In addition, when any one item in a list wraps multiple lines, leave a blank line between each item in the list.
- This is the first line of the item. This is a continuation of the same item. - This is a separate item. - This is another item in the same list.
A common pattern is to bold a short lead-in term at the start of each item, followed by a full sentence explaining it. Use the following syntax. The lead-in term is terminated by a full-stop, rather than by a colon or hyphen, for the best accessibility.
* *Performance.* The system responds to user input within 100ms under normal load. * *Reliability.* The system continues to operate correctly in the presence of hardware or software faults. * *Scalability.* The system handles growth in data volume, traffic, or complexity without a redesign. * *Maintainability.* The system is easy for engineers to understand, modify, and extend over time.
Another pattern supported by Markdown is to inject a newline after the lead-in text, and then indent subsequent lines. This has the visual effect of better differentiating the lead-in text, so it is rendered more like a heading.
* *Performance.* + The system responds to user input within 100ms under normal load. * *Reliability.* + The system continues to operate correctly in the presence of hardware or software faults. * *Scalability.* + The system handles growth in data volume, traffic, or complexity without a redesign. * *Maintainability.* + The system is easy for engineers to understand, modify, and extend over time.
For lists of key-value pairs, place the colon inside the bold marker.
* *Status:* Active * *Owner:* Platform team * *Region:* eu-west-1 * *Version:* 2.4.0
GFM task lists MAY be used where the rendering platform supports them:
- [x] Completed task - [ ] Outstanding task
Links
Links are written by enclosing the link text in square brackets, immediately followed by the URL in parentheses.
My favorite search engine is [Duck Duck Go](https://duckduckgo.com).
A link MUST NOT be broken across lines. The whole construct — the bracketed text, the parenthesized URL, and the boundary between them — MUST sit on a single source line, even where that takes the line past the usual line length limit.
A soft wrap between the closing ] and the opening ( breaks the link
outright. CommonMark stops treating it as a link and renders the raw syntax as
literal text. A wrap inside the bracketed text is less destructive but still
puts a line break in the middle of the rendered link text. Where a long URL
makes the line uncomfortable, use a reference-style link instead, as described
below.
An optional title may be added in double quotes after the URL. The title is displayed as a tooltip in most renderers.
[Duck Duck Go](https://duckduckgo.com "A privacy-focused search engine")
Bare URLs and email addresses SHOULD be enclosed in angle brackets to ensure they are auto-linked:
<https://www.example.com> <user@example.com>
To prevent a URL from being auto-linked, wrap it in backticks:
`https://www.example.com`
Reference-style links
Reference-style links separate the link text from the URL, which can improve
readability in documents that contain many long URLs. The link is written as
[text][label], and the URL is defined elsewhere as
[label]: url "optional title".
See the [CommonMark spec][cm] for details. [cm]: https://spec.commonmark.org/ "CommonMark Specification"
Reference definitions MAY be placed immediately after the paragraph that uses them or at the end of the document.
URL encoding
Spaces and parentheses in URLs can cause parsing problems. Spaces in URLs SHOULD
be URL-encoded as %20. Where a URL contains parentheses, consider using
reference-style links or HTML <a> tags.
Images
Images are written with an exclamation mark, followed by alternative text in square brackets, and the image path or URL in parentheses. An optional title may follow in double quotes.

All images MUST have alternative text. The alternative text SHOULD concisely describe the content of the image; see TS-26: Technical Writing Style Guide for guidance.
To link an image, wrap the image syntax in a link:
[](https://www.example.com)
Markdown does not provide a standard way to set image dimensions. Where sizing
or alignment is required, use an HTML <img> tag with explicit width and
height attributes.
Blockquotes
A blockquote is written by prefixing a line with a right angle bracket (>) and
a single space.
> This is a quoted paragraph.
Blockquotes with multiple paragraphs require a > on each blank line between
paragraphs:
> First paragraph. > > Second paragraph.
Blockquotes MAY be nested by adding additional > characters. Other block
elements, such as lists and code blocks, MAY be included inside a blockquote by
prefixing their lines with >.
Blockquotes SHOULD be surrounded by blank lines.
Callouts
Callouts, also known as alerts or admonitions, are a GitHub extension that renders a blockquote as a highlighted, labeled panel. A callout is written as a blockquote whose first line is a bracketed, exclamation-prefixed keyword.
> [!NOTE] > Useful information that readers should know.
Five keywords are supported: [!NOTE], [!TIP], [!IMPORTANT], [!WARNING],
and [!CAUTION]. The keyword MUST be uppercase and on its own line, with the
callout content following on subsequent blockquote lines.
Callouts MAY be used in documents targeting GitHub. Because they are a GitHub extension rather than part of the GFM specification, they are not portable: on renderers that do not support them, they degrade to an ordinary blockquote containing the literal keyword text. For admonition-heavy technical documentation that must render across platforms, AsciiDoc is RECOMMENDED instead. See TS-28: AsciiDoc.
Tables
Tables are a GFM extension. They are written with a header row separated by hyphens, and cells separated by pipes.
| Syntax | Description | | ----------- | ----------- | | Header | Title | | Paragraph | Text |
A pipe SHOULD be placed at the start and end of each row for portability. The hyphens in the separator row need not be aligned with the column widths; the rendered output is unaffected.
Column alignment is controlled by colons in the separator row:
| Left | Center | Right | | :----- | :----: | ----: | | Left | Center | Right |
Tables SHOULD be used sparingly in Markdown. Markdown tables do not support cell spanning, and block-level elements such as lists, headings, or nested tables cannot be placed inside cells. For complex tables, use AsciiDoc; see TS-28: AsciiDoc.
To display a literal pipe character inside a cell, use its HTML character
reference (|).
Horizontal rules
A horizontal rule is created with three or more asterisks (*), hyphens
(---), or underscores (_) on a line by themselves.
Hyphens (---) are RECOMMENDED for consistency. A blank line MUST precede a
horizontal rule; without one, a line of --- immediately after text may be
interpreted as a setext heading.
Horizontal rules SHOULD be used sparingly to separate sections. Prefer headings for structuring content.
Escaping characters
A literal character that would otherwise be interpreted as Markdown formatting
may be escaped by prefixing it with a backslash (\).
\* This is not a list item.
The following characters MAY be escaped:
\ ` * _ { } [ ] < > ( ) # + - . ! |Escaping SHOULD be used only where necessary. Prefer to restructure content to avoid ambiguity — for example, by adding blank lines around elements — rather than escaping many characters.
HTML
Most Markdown processors allow inline HTML. HTML is useful where Markdown lacks
an equivalent, such as for setting image dimensions, controlling text color, or
using <details> disclosure blocks.
This <em>word</em> is italic.
Block-level HTML elements such as <div>, <table>, and <pre> MUST be
separated from surrounding Markdown by blank lines, and SHOULD NOT be indented.
Important
Markdown syntax is not processed inside block-level HTML tags. bold inside
<div>bold</div> will be rendered as literal asterisks, not as bold text.
HTML SHOULD be used sparingly. Documents that rely heavily on HTML lose the portability and readability benefits of Markdown. For content that requires rich HTML, consider whether a more capable format such as AsciiDoc or direct HTML is more appropriate.
Footnotes
Footnotes are an extension supported by GFM and several other processors, but
not by pure CommonMark. A footnote reference is written as [^label], and the
footnote content is defined as [^label]: text.
Here is a statement.[^1] [^1]: The supporting reference.
Footnote labels only correlate the reference with the definition; the rendered output is numbered sequentially regardless of the label.
Because footnote support is not universal, footnotes SHOULD be avoided in documents that must render across a wide range of Markdown processors. Prefer inline links for citations in portable documents.
Line length and wrapping
Lines SHOULD NOT exceed 80 characters. Content longer than this SHOULD be "soft wrapped" — that is, continued on the next line without a trailing backslash or trailing spaces. CommonMark joins consecutive lines within a paragraph into a single line in the rendered output, so soft wrapping does not affect how the document renders.
The purpose of this constraint is to ensure that files render identically in every editor, regardless of the editor’s own line-wrapping width or settings.
Lines MUST NOT exceed 160 characters, except in very special circumstances where this cannot be achieved — for example, in tables or long URLs that cannot themselves be broken across lines.
A soft wrap MUST NOT be inserted within an inline formatting unit, such as bold
or italic text, so as to preserve the formatting markers (eg. ** or _)
alongside the text they format.
The same applies to links, which MUST NOT be broken across lines. Where keeping a link intact takes a line past 80 characters, the link wins.
Hard line breaks (two trailing spaces or a trailing backslash) SHOULD be used only where a break is semantically required, such as in postal addresses or song lyrics. Prefer the trailing backslash format, over two trailing spacings, for clarity and to avoid auto-formatters breaking the formatting by removing end-of-line trailing whitespace.
Note
Configure your editor to strip trailing whitespace on save, and to highlight any trailing whitespace that introduces a hard line break. This prevents accidental, invisible line breaks.
Tooling
A linter SHOULD be used to enforce consistent Markdown style across a project. markdownlint is RECOMMENDED. It is configurable and widely supported.
A code formatter such as Prettier MAY be used to automate wrapping, list indentation, and code-block formatting. Formatting and linting SHOULD be reconciled so they do not produce conflicting results.
A link checker SHOULD be run as part of continuous integration to detect broken internal and external links.
Editor configuration SHOULD ensure:
- Trailing whitespace is highlighted.
- Files end with a single newline character.
- Indentation uses spaces, not tabs.