sourcecodestack Team
Tools, guides & how-tos
Markdown is the lingua franca of technical writing. From GitHub README files and documentation sites to Notion pages and Stack Overflow answers, Markdown lets you add structure and meaning to plain text without reaching for a word processor. This cheat sheet covers every major element — with copy-paste examples — so you can write clean, portable Markdown every time.
If you want to experiment as you read, open the Markdown Editor and try each snippet live.
Markdown was created by John Gruber in 2004 as a lightweight text-to-HTML conversion tool. The design goal was that raw Markdown source should be readable as-is — it should look like naturally formatted plain text, not like markup code. Over the years, multiple dialects emerged. The two most important today are:
Unless noted, everything in this guide works in both dialects.
Use the # character followed by a space. The number of # symbols maps to the HTML heading level.
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
ATX style (shown above) is the modern standard. An older Setext style also exists for H1 and H2:
Heading 1
=========
Heading 2
---------
Prefer ATX — it works for all six levels and is unambiguous.
CommonMark rule: you must have a space after the #. #heading without a space is rendered as a paragraph, not a heading.
**bold text**
__also bold__
Use **double asterisks** — it is unambiguous. Underscores work but can clash with variable names like my_variable_name.
*italic text*
_also italic_
***bold and italic***
**_bold and italic_**
~~strikethrough text~~
This is a GitHub Flavored Markdown extension and is not part of CommonMark. It renders in GitHub, GitLab, and most modern editors.
Use the `console.log()` function for debugging.
Backticks preserve whitespace and disable all other Markdown formatting inside them. To include a literal backtick inside inline code, use double backticks as the delimiter:
`` Use `backticks` like this ``
Use -, *, or + followed by a space. Pick one character and stick with it for consistency.
- Item one
- Item two
- Nested item (two spaces)
- Another nested item
- Item three
Result:
Nesting rule: indent nested items by exactly two spaces (or four spaces in some parsers). Using a tab character can work but is not portable across all Markdown renderers.
1. First item
2. Second item
3. Third item
1. Nested ordered item
2. Another nested item
A useful trick: you can use 1. for every item and most parsers will auto-number them. This makes reordering easier without renumbering.
1. First
1. Second
1. Third
- [x] Write the introduction
- [x] Add code examples
- [ ] Review and publish
- [ ] Share on social media
Renders as interactive checkboxes on GitHub. The [x] marks a completed task; [ ] marks an incomplete one. This is one of the most useful GFM extensions for project planning in README files.
[link text](https://example.com)
[link with title](https://example.com "Hover tooltip")
Useful when the same URL appears multiple times, or when you want to keep URLs out of the prose:
Visit [Google][search-engine] or [Bing][search-engine-2].
[search-engine]: https://google.com
[search-engine-2]: https://bing.com
The reference definitions can be placed anywhere in the document — conventionally at the bottom, like footnotes.
In GFM, bare URLs are automatically linked:
https://example.com
In CommonMark, you must use angle brackets: <https://example.com>
Images follow the same syntax as links but with a leading !:


The alt text is important for accessibility — screen readers read it aloud. Never leave it empty unless the image is purely decorative.
Reference-style image:
![Logo][logo-ref]
[logo-ref]: /assets/logo.png "Company Logo"
[](https://example.com)
This wraps an image in a link — useful for badges in README files.
Fenced code blocks use triple backticks (or triple tildes). Always add a language identifier — it enables syntax highlighting in GitHub, VS Code, and most documentation platforms.
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet('World'));
```
Common language identifiers:
| Language | Identifier |
|---|---|
| JavaScript | javascript or js |
| TypeScript | typescript or ts |
| Python | python or py |
| Shell / Bash | bash or sh |
| SQL | sql |
| HTML | html |
| CSS | css |
| JSON | json |
| YAML | yaml or yml |
| Markdown | markdown or md |
| Diff | diff |
| Plain text | text or plaintext |
- const oldFunction = () => false;
+ const newFunction = () => true;
Lines prefixed with - render in red; lines prefixed with + render in green. Invaluable for showing what changed.
The older syntax uses four spaces of indentation. Avoid it — fenced blocks are clearer and support language hints.
// This is an indented code block (4 spaces)
console.log('old style');
Use > to create blockquotes. Chain multiple > for nested quotes.
> "Programs must be written for people to read, and only incidentally
> for machines to execute."
>
> — Harold Abelson
“Programs must be written for people to read, and only incidentally for machines to execute.”
— Harold Abelson
Nested blockquotes:
> Outer quote
>
> > Inner quote (nested)
> >
> > > Deeply nested
Blockquotes can contain other Markdown elements — lists, code, headings — making them useful for callout boxes in documentation.
Tables are a GFM extension (not standard CommonMark). They use pipes | and hyphens - for the header separator row.
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |
Colons in the separator row control alignment:
| Left Aligned | Center Aligned | Right Aligned |
|:-------------|:--------------:|--------------:|
| text | text | text |
| 1234 | 5678 | 9012 |
| Left Aligned | Center Aligned | Right Aligned |
|---|---|---|
| text | text | text |
| 1234 | 5678 | 9012 |
Table tips:
<table> tags if you need rowspan or colspan.Three or more hyphens, asterisks, or underscores on a line by themselves create a <hr> element:
---
***
___
Caution: a line of hyphens directly below a paragraph (with no blank line separating them) creates a Setext H2 heading, not a horizontal rule. Always put a blank line before ---.
| Feature | CommonMark | GitHub Flavored Markdown |
|---|---|---|
| Tables | Not supported | Supported |
| Task lists | Not supported | Supported |
Strikethrough (~~) |
Not supported | Supported |
| Bare URL autolinks | Not supported | Supported |
Emoji shortcodes (:smile:) |
Not supported | Supported |
| Footnotes | Not supported | Supported (beta) |
| HTML blocks | Allowed (restricted) | Allowed (restricted) |
| Tight list paragraph handling | Strict spec | Same |
If your Markdown will be read on GitHub, GitLab, or a platform that explicitly states GFM support, you can safely use all GFM extensions. For maximum portability (e.g., a static site generator, a wiki engine, or a tool you do not control), stick to CommonMark.
A README is the front door of your project. Good README structure follows a predictable order so readers can quickly find what they need. Here is the recommended section order:
Start with the project name as an H1, then a row of status badges (build, coverage, license, version). Badges give immediate health signals.
# MyProject
[](link)
[](LICENSE)
One sentence explaining what the project does. Imagine someone has five seconds. What do they need to know?
For long READMEs, a TOC with anchor links helps readers jump to sections:
## Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [Contributing](#contributing)
Exact, copy-paste steps. Do not assume the reader’s environment. Name every prerequisite.
## Installation
**Prerequisites:** Node.js 18+ and pnpm 8+
```sh
git clone https://github.com/user/myproject.git
cd myproject
pnpm install
### 5. Quick Start / Usage
Show the most common use case first, with a working code example. This is often the most-read section.
### 6. Configuration
Document all environment variables, config files, and flags. A table works well here.
### 7. API Reference (if applicable)
For libraries, document the public API. Link to generated docs if they exist.
### 8. Contributing
How to open issues, submit PRs, and run tests. Link to a `CONTRIBUTING.md` for detailed guidelines.
### 9. License
State the license and link to the `LICENSE` file.
```markdown
## License
MIT — see [LICENSE](LICENSE) for details.
These are the errors that trip up even experienced writers.
Many Markdown elements require a blank line before them to be recognized.
This is a paragraph.
## This heading will NOT render correctly
This is a paragraph.
## This heading WILL render correctly
Blank lines are also required before and after:
An unclosed triple-backtick fence will swallow the rest of the document into a code block. Always close your fences.
```python
def broken():
pass
# Missing closing fence — everything below becomes code!
Different parsers handle tabs differently inside lists. Use spaces — specifically two or four — for nested list items. Do not mix tabs and spaces.
- Parent
- Child (2 spaces — works everywhere)
- Child (tab — unreliable)
In CommonMark, underscores cannot be used for emphasis inside a word:
my_variable_name ← the underscores do NOT become italic
*my_variable_name* ← use asterisks if you need emphasis here
Parentheses in URLs must be escaped or encoded:
<!-- Broken -->
[Link](https://example.com/page(1))
<!-- Fixed: escape with backslash -->
[Link](https://example.com/page\(1\))
<!-- Fixed: percent-encode -->
[Link](https://example.com/page%281%29)
Markdown does not escape HTML entities automatically in all contexts. Inside HTML blocks, use & for &, < for <, etc. Inside regular Markdown paragraphs, you can write & and < directly and most parsers will handle them.
# in Headings#Title is a paragraph starting with #Title. # Title is a heading. This is one of the most common typos.
A single line break in Markdown source renders as a space, not a new line. To force a line break, end the line with two trailing spaces or use <br>:
Line one
Line two (two trailing spaces above force a line break)
This is subtle and easy to miss because trailing spaces are invisible in most editors. Consider using <br> instead for clarity.
Markdown has become the default format in many contexts:
| Platform | Where Markdown Appears |
|---|---|
| GitHub / GitLab | README files, issues, pull requests, wikis, comments |
| Stack Overflow | Questions, answers, comments |
| Posts and comments (partial Markdown) | |
| Notion | Pages and databases |
| Obsidian | All notes (with extensions) |
| Confluence | Pages (via the Markdown macro or import) |
| Discord | Messages (partial: bold, italic, code) |
| Slack | Messages (simplified Markdown) |
| Jekyll / Hugo / Eleventy | Blog posts and page content |
| Docusaurus / MkDocs | Documentation sites |
| Jupyter Notebooks | Prose cells |
| VS Code | Markdown preview, README editing |
Markdown files conventionally use the .md extension (sometimes .markdown). YAML front matter — a block of key-value pairs at the very top, delimited by --- — is widely used by static site generators to attach metadata:
---
title: My Blog Post
date: 2026-06-04
tags: [markdown, writing]
---
# My Blog Post
Content starts here.
To display a literal Markdown character that would otherwise be interpreted as formatting, prefix it with a backslash:
\*not italic\*
\# not a heading
\[not a link\](not-a-url)
Characters you may need to escape: \, `, *, _, {, }, [, ], (, ), #, +, -, ., !
Most Markdown parsers allow raw HTML. Use it sparingly — only when Markdown cannot express what you need:
<details>
<summary>Click to expand</summary>
Hidden content here. Note the blank lines around the Markdown inside HTML blocks.
</details>
This renders as a collapsible section on GitHub — handy for long installation instructions or changelogs.
<kbd>Ctrl</kbd> + <kbd>C</kbd>
The <kbd> tag renders as keyboard key styling, which Markdown has no native equivalent for.
| Element | Syntax |
|---|---|
| H1 Heading | # Heading |
| H2 Heading | ## Heading |
| Bold | **text** |
| Italic | *text* |
| Bold + Italic | ***text*** |
| Strikethrough | ~~text~~ |
| Inline code | `code` |
| Fenced code block | ```lang ... ``` |
| Unordered list | - item |
| Ordered list | 1. item |
| Task list | - [x] done / - [ ] todo |
| Link | [text](url) |
| Image |  |
| Blockquote | > text |
| Table | | col | col | |
| Horizontal rule | --- |
| Line break | two trailing spaces |
| Escape character | \* |
markdownlint (available as a VS Code extension, CLI, and GitHub Action) enforces consistent style — heading levels, blank lines, line length, and more. Adding it to a CI pipeline catches formatting issues before they merge.
# ProjectName
[]()
[](LICENSE)
A one-sentence description of what the project does.
## Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [Contributing](#contributing)
- [License](#license)
## Installation
**Prerequisites:** Node.js 20+
```sh
npm install projectname
import { doThing } from 'projectname';
const result = doThing('input');
console.log(result);
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
HTTP port to listen on |
LOG_LEVEL |
info |
Logging verbosity |
PRs welcome. Please open an issue first to discuss the change.
Run npm test before submitting.
MIT — see LICENSE for details.
---
## Conclusion
Markdown strikes a rare balance: it is simple enough to write in a plain text editor with no tooling, yet powerful enough to produce beautifully formatted documentation, READMEs, and blog posts. The learning curve is shallow — most people are productive within an hour.
The keys to writing great Markdown are consistency (pick one style for bullets, headings, emphasis and stick with it), adding language hints to every code fence, and respecting the blank-line rules that many parsers require.
For a hands-on environment to practice everything from this guide, try the [Markdown Editor](/tools/markdown-editor) — you can paste any snippet from this post and see the rendered result immediately.
sourcecodestack Team
We build free, privacy-first browser tools and write practical guides on how to use them. Everything runs on your device — no uploads, no sign-ups.
A site will not load. Before you clear your cache, reboot the router, or file an angry support ticket, answer …
You have two JSON payloads — maybe a staging API response and a production one, or a config file before and af…
API Client Guide: Test APIs Online Without Postman Testing an API should be fast and frictionless. You have an…