Markdown Code Block: Complete Syntax Guide (2026)
TL;DR: Markdown code blocks come in two forms — inline (
backtick) and fenced (```triple backticks). The CommonMark specification 0.31.2 defines both in sections 6.1 (code spans) and 4.5 (fenced code blocks). Add a language tag directly after the opening fence (e.g.,```python) to enable syntax highlighting. Four-space indented blocks also work but do not support language tags.
Code is one of the most important things to format correctly in Markdown. A raw snippet dropped into a paragraph loses indentation, gets special characters mangled, and becomes nearly impossible to read. Markdown code blocks preserve whitespace, apply monospace fonts, and — with a language tag — enable full syntax highlighting. Whether you are writing a README, a technical blog post, or documentation, getting code blocks right is non-negotiable.
This guide covers every code block format defined by CommonMark 0.31.2: inline code spans, fenced code blocks, indented code blocks, language tags for syntax highlighting, escaping backticks, and code inside lists. It also maps behavior across GitHub, GitLab, VS Code, Obsidian, and Reddit so you know what to expect before you publish. If you are also working with tables or blockquotes alongside code, see the markdown blockquote guide and the markdown table guide for the full picture.
What Is Inline Code in Markdown?
Inline code wraps a word or short phrase in single backtick characters, producing a <code> element inside the surrounding paragraph. It is defined in CommonMark 0.31.2, section 6.1 and works in every Markdown renderer without exception.
Install `node` before running `npm install`.This renders as: Install node before running npm install.
Use inline code for:
- Command names:
git commit,npm run build - File names and paths:
README.md,/usr/local/bin - Variable and function names:
userCount,render() - Short code expressions:
x = x + 1 - Keyboard shortcuts written as keys:
Cmd+Shift+V
Do not use inline code for multi-line snippets or anything that benefits from syntax highlighting — that is what fenced code blocks are for.
How Do You Put a Backtick Inside Inline Code?
The CommonMark spec (section 6.1) allows you to use any equal number of backtick characters as the opening and closing delimiter. To include a literal backtick inside the code span, use double backticks as the fence:
Use `` ` `` to start an inline code span.
Use `` `code with backtick` `` as a double-fence example.The rule: the opening and closing sequences must be the same length, and the content must not contain an identical uninterrupted sequence of backticks. This scales to any depth — triple backticks as delimiter for content containing double backticks, and so on.
How Do You Create a Fenced Code Block in Markdown?
A fenced code block places three or more backtick characters on their own line before and after the code. This is CommonMark 0.31.2, section 4.5. The opening fence and closing fence must use the same number of backticks (three is standard), and the closing fence must be on its own line.
```
function greet(name) {
return `Hello, ${name}!`
}
```You can also use three or more tilde characters (~~~) as the fence. Tildes and backticks are interchangeable, though backticks are far more common in practice. The only case where tildes are useful is when your code content itself contains triple backticks.
Adding a Language Tag for Syntax Highlighting
Write the language identifier directly after the opening fence with no space or punctuation between them:
```javascript
function greet(name) {
return `Hello, ${name}!`
}
``````python
def greet(name: str) -> str:
return f"Hello, {name}!"
``````bash
#!/bin/bash
echo "Hello, $1"
```The language tag is passed to the syntax highlighter as a hint. It does not affect parsing — CommonMark treats the info string after the fence as opaque text. Renderers that support highlighting (like MacMD Viewer, GitHub, VS Code) use it to select the correct tokenizer. Renderers that do not support highlighting ignore it silently.
MacMD Viewer applies highlight.js for syntax highlighting inside fenced code blocks. Every language tag recognized by highlight.js — over 190 in total — renders with full token coloring. This includes everything from mainstream languages like Python and JavaScript to niche ones like Elixir, Haskell, and Nix.
Which Language Tags Work Across Platforms?
Language support depends on the syntax highlighting library the platform uses. Here are the most commonly used tags and their cross-platform status:
| Language tag | GitHub | GitLab | VS Code | Obsidian | MacMD Viewer | |
|---|---|---|---|---|---|---|
python | Yes | Yes | Yes | Yes | Yes | Yes |
javascript | Yes | Yes | Yes | Yes | Yes | Yes |
typescript | Yes | Yes | Yes | Yes | Yes | Yes |
bash / sh | Yes | Yes | Yes | Yes | Yes | Yes |
html | Yes | Yes | Yes | Yes | Yes | No |
css | Yes | Yes | Yes | Yes | Yes | No |
json | Yes | Yes | Yes | Yes | Yes | No |
yaml / yml | Yes | Yes | Yes | Yes | Yes | No |
sql | Yes | Yes | Yes | Yes | Yes | No |
go | Yes | Yes | Yes | Yes | Yes | No |
rust | Yes | Yes | Yes | Yes | Yes | No |
java | Yes | Yes | Yes | Yes | Yes | No |
cpp / c++ | Yes | Yes | Yes | Yes | Yes | No |
markdown | Yes | Yes | Yes | Yes | Yes | No |
diff | Yes | Yes | Yes | Yes | Yes | No |
Reddit renders code blocks as plain monospace text regardless of language tag — it has no syntax highlighting. All other platforms in the table apply color-coded token highlighting when a valid language tag is present.
Alias tip: Many languages accept multiple tag names.
jsandjavascriptare equivalent on all platforms.sh,bash, andshellall activate shell highlighting.ymlworks the same asyaml. When in doubt, use the full language name.
What Is an Indented Code Block?
An indented code block uses four or more leading spaces on every line of the code. This is the original Markdown syntax defined by John Gruber and retained in CommonMark 0.31.2, section 4.4.
Here is a code block created with indentation:
def greet(name):
return f"Hello, {name}!"
And the prose continues here.The indented block must be preceded by a blank line when it follows a paragraph. The four leading spaces are stripped in the rendered output — they are the delimiter, not part of the code.
When to use indented code blocks:
- Compatibility with very old Markdown parsers that do not support fenced blocks
- When the code itself starts with triple backticks (rare edge case)
When not to use indented code blocks:
- Inside list items — the indentation interacts with list parsing in unpredictable ways across parsers
- When you want syntax highlighting — indented blocks have no mechanism for a language tag
- In any modern context — fenced blocks are cleaner, more explicit, and universally supported
For every new document, use fenced code blocks with triple backticks. Indented code blocks are a legacy syntax that you will encounter when reading old documentation, but should not write in new content.
How Do You Put a Code Block Inside a List?
Code blocks inside list items are one of the trickiest aspects of Markdown formatting. The CommonMark specification (section 5.3) requires that continuation content in a list item align with the item's content start position. For code blocks, that means the entire fenced block — opening fence, code, and closing fence — must be indented.
For an ordered list with a 1. marker, the content starts at column four (after 1. ), so indent by three spaces:
1. Install the dependencies:
```bash
npm install
```
2. Start the development server:
```bash
npm run dev
```For an unordered list with a - marker, the content starts at column three (after - ), so indent by two or three spaces depending on the renderer:
- Clone the repository:
```bash
git clone https://github.com/example/repo.git
```
- Change into the directory:
```bash
cd repo
```The blank line between the list item text and the opening fence is required. Without it, some parsers treat the fence as a literal string inside the list item rather than as a code block. See the markdown lists guide for the full rules on list item continuation content.
Common Mistake: Wrong Indentation Breaks the List
If the code block is not indented enough, the list closes prematurely and the code block renders as a top-level block outside the list:
1. Run the build:
```bash
npm run build
```
2. This item no longer connects to item 1 on most parsers.Fix: always indent the fence to align with the text content of the list item, not the list marker.
What Are the Most Common Code Block Mistakes?
Five patterns cause most broken code block rendering. Each fails silently — no error, just wrong output.
Mistake 1: Forgetting the closing fence
The opening and closing fences must both be present and on their own lines. A missing closing fence causes the entire rest of the document to be treated as code on some parsers, or the block to not render at all on others.
Mistake 2: Mismatched fence lengths
If the opening fence uses four backticks, the closing fence must also use four backticks. Three backticks in the middle of the code content will close the block early if the opening used three.
````markdown
This block uses four backticks so that the ```triple``` backtick inside does not close it.
````Mistake 3: Space between the fence and the language tag
The language identifier must follow the opening fence with no space: ```python (correct) vs ``` python (incorrect). CommonMark 0.31.2 (section 4.5) specifies that the info string begins at the first non-space character after the fence — but many renderers are lenient. Do not rely on that leniency.
Mistake 4: Missing blank line before the fence inside a list
Without a blank line between the list item text and the opening fence, the fence characters may be interpreted as literal text. Always separate the item text from any embedded content block with a blank line.
Mistake 5: Using inline code for multi-line snippets
Single backticks are for single-line inline spans only. CommonMark (section 6.1) strips leading and trailing spaces and normalizes internal whitespace in code spans — newlines become spaces. Multi-line code must use fenced or indented code blocks.
How Do Markdown Code Blocks Convert to HTML?
Understanding the HTML output helps debug rendering and styling issues. The CommonMark specification defines the exact mapping:
Inline code:
Use `console.log()` to debug.Produces:
<p>Use <code>console.log()</code> to debug.</p>Fenced code block without language tag:
```
hello world
```Produces:
<pre><code>hello world
</code></pre>Fenced code block with language tag:
```python
print("hello")
```Produces:
<pre><code class="language-python">print("hello")
</code></pre>The language-python class is the standard CSS class convention from the CommonMark spec (section 4.5, info string). Syntax highlighters like highlight.js and Prism.js detect this class to apply token coloring. You can convert your Markdown to HTML and inspect the exact output using the free Markdown to HTML converter on this site.
How Do Code Blocks Behave Across Platforms?
The core fenced code block syntax is consistent across all CommonMark-compliant renderers. Differences appear in syntax highlighting support and language tag handling:
| Platform | Fenced blocks | Indented blocks | Syntax highlighting | Language tag source |
|---|---|---|---|---|
| GitHub (GFM) | Yes | Yes | Yes | Linguist |
| GitLab (GLFM) | Yes | Yes | Yes | Rouge |
| VS Code | Yes | Yes | Yes | highlight.js / TextMate |
| Obsidian | Yes | Yes | Yes | CodeMirror |
| MacMD Viewer | Yes | Yes | Yes | highlight.js |
| Yes | Yes | No | — | |
| CommonMark (strict) | Yes | Yes | No (spec) | — (opaque) |
Note that CommonMark itself defines no syntax highlighting — it is a rendering concern left to the implementation. The spec only standardizes parsing and HTML output, including the language-* class on <code> elements.
GitHub uses Linguist for language detection and applies its own syntax highlighting theme. GitHub also supports mermaid as a language tag to render Mermaid diagrams inline.
VS Code previews Markdown with highlight.js by default. The language tags match highlight.js aliases. The same rendering applies inside Jupyter notebooks — see the Jupyter Markdown guide for notebook-specific behavior.
Reddit renders all code blocks as plain monospace text in the new redesign. Language tags are ignored. Old Reddit (.old.reddit.com) renders fenced code blocks only if you are using Markdown mode, not the rich-text editor.
How Do You Escape Backticks in Markdown?
There are two contexts where backtick escaping matters:
Inside inline code spans: Use a longer backtick sequence as the delimiter. To show a single backtick, wrap the span in double backticks: `. To show double backticks, use triple backticks as the delimiter.
Outside code spans: A single backtick that is not part of a code span pair can be escaped with a backslash: ``` renders a literal backtick character. However, this is only reliable for isolated backticks — do not rely on backslash escaping to control code span parsing.
Inside fenced code blocks: No escaping is needed. Everything between the opening and closing fence is treated as literal text. The only character sequence you cannot include directly is the exact fence sequence on its own line (e.g., three backticks if your fence uses three). Use a tilde fence instead:
~~~
This block contains ``` triple backticks ``` without closing the block.
~~~How Do You Preview Markdown Code Blocks on macOS?
macOS Quick Look shows .md files as plain text, which means you cannot verify syntax highlighting, check that your closing fences are in the right place, or confirm that code blocks inside lists are rendering correctly — without a third-party tool.
MacMD Viewer is a native macOS app built for exactly this. It renders all Markdown code blocks in real time as you edit in your preferred text editor — fenced blocks with full syntax highlighting via highlight.js, indented blocks, inline code, and code blocks nested inside lists. The live preview catches unclosed fences and broken list indentation immediately, before they reach GitHub or your documentation platform. MacMD Viewer registers as the default .md handler, so double-clicking any Markdown file opens a rendered preview. ($19.99, one-time purchase.)
VS Code — Press Cmd+Shift+V on any open .md file. The built-in preview handles fenced code blocks and syntax highlighting using VS Code's own language detection.
Terminal with Glow — brew install glow and run glow file.md. Glow renders code blocks in the terminal with color highlighting and is useful for quick checks without opening a GUI app.
Frequently Asked Questions
How do you write a code block in Markdown?
Open a line with three backtick characters (```), write your code on the following lines, then close with another line of three backticks. Optionally add a language tag after the opening fence (```python) to enable syntax highlighting. This is a fenced code block per the CommonMark 0.31.2 specification, section 4.5.
How do you add syntax highlighting to a Markdown code block?
Write the language name immediately after the opening fence with no space: ```javascript, ```python, ```bash. The renderer uses this tag to apply color highlighting. Supported languages depend on the platform — GitHub, GitLab, VS Code, Obsidian, and MacMD Viewer all support the major languages including Python, JavaScript, TypeScript, Bash, HTML, CSS, JSON, YAML, SQL, Go, Rust, Java, and C++.
What is the difference between inline code and a code block in Markdown?
Inline code uses single backticks around a short phrase (like this) and renders as a <code> element within a paragraph — used for variable names, commands, and file paths. A code block uses triple backticks on their own lines and renders as <pre><code> — used for multi-line snippets that need to preserve indentation and optionally receive syntax highlighting.
Why is my Markdown code block not rendering correctly?
Check these in order: (1) the closing fence is present on its own line, (2) the opening and closing fences use the same number of backtick characters, (3) there is no space between the fence and the language tag, (4) if the block is inside a list item, the fence is indented to align with the item content and preceded by a blank line. You can also paste your Markdown into the free Markdown to HTML converter to inspect the exact HTML output.
Can you use triple backticks inside a fenced code block?
Yes, by using a longer or different fence. Use four backticks (````) as the outer fence, or switch to a tilde fence (~~~). Any sequence that does not appear as a complete line matching the opening fence length will be treated as content.
How do you format code in the markdown cheat sheet?
The markdown cheat sheet covers the quick reference. For code: single backticks for inline, triple backticks with optional language tag for blocks, and four-space indentation as the legacy fallback. The markdown text formatting guide covers how code formatting interacts with bold, italic, and other inline styles.
Continue reading with AI
Content licensed under CC BY 4.0. Cite with attribution to MacMD Viewer.