Markdown is a lightweight markup language created by John Gruber in 2004. It was designed with one goal in mind: to let writers format plain text in a way that is both readable as-is and convertible into clean HTML. Unlike HTML, which requires tags that obscure the actual content, Markdown uses simple punctuation symbols that look natural even before they are rendered.
Today, Markdown is one of the most widely used writing formats on the internet. It is the standard format for GitHub READMEs, technical documentation, blog posts, note-taking apps, and developer platforms — including this one. If you write on the web, you will encounter Markdown constantly.
How Markdown Works
Markdown is a plain text format. You write in a .md file using simple syntax, and a Markdown renderer — built into platforms like GitHub, Notion, or your own frontend — converts it into formatted HTML for display. The original text remains readable even without rendering, which is one of Markdown's core design principles.
For example, this Markdown:
## Hello World
This is a **bold** statement and this is _italic_.
Renders as:
Hello World This is a bold statement and this is italic.
The renderer handles the conversion. Your job is just to write.
Markdown Flavours
The original Markdown specification by John Gruber was intentionally minimal. Over time, different platforms extended it with additional features, creating flavours of Markdown. The most important ones to know are:
| Flavour | Where It's Used | Notable Additions |
|---|---|---|
| CommonMark | The standardised base spec | Resolves ambiguities in the original spec |
| GitHub Flavoured Markdown (GFM) | GitHub, GitLab | Tables, task lists, strikethrough, syntax highlighting |
| MDX | React/Next.js projects | Allows JSX components inside Markdown |
Most platforms use GFM or a close variant of it. Everything covered in this topic is supported by GFM unless noted otherwise.
Headings
Headings are created using the # symbol. The number of # symbols corresponds to the heading level — equivalent to HTML's <h1> through <h6>.
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
Always leave a space between the # and the heading text. Heading 1 (#) is the page title and should typically appear only once per document. Use ## and ### for sections and subsections.
Paragraphs and Line Breaks
A paragraph is simply one or more lines of text with a blank line separating it from the next block.
This is the first paragraph.
This is the second paragraph.
To create a line break within a paragraph without starting a new one, end the line with two spaces before pressing Enter. This is a subtle but important distinction — a single Enter without two spaces will not produce a visible line break in most renderers.
Emphasis
| Syntax | Output | Use |
|---|---|---|
**bold** or __bold__ | bold | Strong importance |
*italic* or _italic_ | italic | Stress emphasis |
***bold and italic*** | bold and italic | Both |
~~strikethrough~~ | Deleted or irrelevant text (GFM) |
It is generally preferred to use ** for bold and * for italic to avoid ambiguity, especially when underscores appear in technical terms like variable_names.
Lists
Unordered Lists
Use -, *, or + followed by a space. The convention is to be consistent within a document — - is the most widely used.
- Item one
- Item two
- Item three
Ordered Lists
Use numbers followed by a period. The actual numbers don't matter — Markdown will render them in sequence regardless.
1. First item
2. Second item
3. Third item
Nested Lists
Indent nested items with two or four spaces:
- Parent item
- Child item
- Another child
- Grandchild item
Task Lists (GFM)
Task lists render as checkboxes. Useful for to-do lists and project tracking.
- [x] Completed task
- [ ] Incomplete task
- [ ] Another pending task
Links
Inline Links
[Link text](https://example.com)
Links with Titles
The title appears as a tooltip on hover:
[Link text](https://example.com "Tooltip text")
Reference-Style Links
For long documents with many links, reference-style links keep the text clean by separating the URL from the prose:
[Link text][ref-label]
[ref-label]: https://example.com
Bare URLs
Wrapping a URL in angle brackets turns it into a clickable link:
<https://example.com>
Images
Image syntax is identical to link syntax with an exclamation mark ! prepended. The text in square brackets becomes the alt attribute — important for accessibility.


Images can also use reference-style syntax the same way links do.
Code
Inline Code
Wrap code in single backticks for inline code. Use this for referencing variable names, function names, or short snippets within a sentence.
Use the `console.log()` function to debug.
Fenced Code Blocks
Use triple backticks to create a fenced code block. Specifying a language after the opening backticks enables syntax highlighting in platforms that support it.
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
```
Supported language identifiers include javascript, typescript, jsx, tsx, python, css, scss, html, bash, json, markdown, and many others. Always specify the language when writing code blocks on a platform that renders syntax highlighting.
Blockquotes
Blockquotes are created with the > prefix. They are commonly used for callouts, notes, warnings, and quoted content.
> This is a blockquote.
Blockquotes can be nested:
> Outer quote
>> Inner quote
And they can contain other Markdown elements:
> **Note:** This is an important detail.
> Use blockquotes to draw attention to it.
Tables (GFM)
Tables are created using pipes | and hyphens -. The second row defines column alignment.
| Column 1 | Column 2 | Column 3 |
| :--- | :---: | ---: |
| Left | Center | Right |
| aligned | aligned | aligned |
| Alignment Syntax | Effect |
|---|---|
:--- | Left-aligned (default) |
:---: | Center-aligned |
---: | Right-aligned |
Tables do not need to be perfectly aligned in the source — renderers handle the spacing. However, keeping columns visually aligned in the raw file makes it easier to read and edit.
Horizontal Rules
A horizontal rule creates a thematic break — a visual divider between sections. Use three or more hyphens, asterisks, or underscores on their own line:
---
***
___
Leave a blank line before and after a horizontal rule to avoid it being interpreted as a heading underline.
Escaping Characters
If you need to display a character that Markdown uses as syntax — like *, _, #, or ` — escape it with a backslash:
\*This is not italic\*
\# This is not a heading
HTML in Markdown
Most Markdown renderers allow raw HTML to be embedded directly. This is useful for elements Markdown doesn't natively support, like centering content or adding custom attributes.
<div style="text-align: center;">
This text is centered.
</div>
Use this sparingly. Embedding too much HTML defeats the purpose of Markdown's simplicity and may not render correctly across all platforms.
Best Practices
- Use one
#heading per document — it acts as the page title. - Leave blank lines between blocks — between headings, paragraphs, lists, and code blocks, to avoid rendering ambiguity.
- Specify languages in code blocks — always add the language identifier for proper syntax highlighting.
- Use
-for unordered lists — consistent and widely supported. - Write alt text for images — important for accessibility and SEO.
- Prefer
**over__for bold — avoids issues with underscores in technical identifiers. - Keep tables simple — complex nested content inside table cells is poorly supported across renderers.