Markdown Code Blocks

Three backticks, a language name, and your code keeps its shape and gains its colours. The syntax is small; what trips people up is the edges — which language names are accepted, how to nest a fence inside a fence, and what happens when you get the name wrong.

Every block below is highlighted by Shiki, the engine behind VS Code, running through the same pipeline that renders a published paste. 232 languages are available.

Fenced code blocks

Three backticks open a block and three close it. Everything between is preserved exactly — indentation, blank lines and any markdown characters, which stop being markdown inside a fence.

You write
```
function greet(name) {
  return "Hello, " + name
}
```
You get
function greet(name) {  return "Hello, " + name}

Without a language after the opening fence you get a code block with no colouring. It still preserves whitespace, which is often all you need for logs or plain output.

Adding a language

Write the language directly after the opening backticks. That is the whole syntax, and it is what turns a grey block into a highlighted one.

You write
```python
def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a
```
You get
python
def fib(n):    a, b = 0, 1    for _ in range(n):        a, b = b, a + b    return a

Highlighting here is done by Shiki, the same engine VS Code uses, so the result matches what you already see in your editor rather than approximating it.

Short aliases work too

Most languages accept an abbreviation as well as a full name — 232 languages are available, with 96 aliases between them. Write whichever you would type by habit.

You write
```js
const x = [1, 2, 3].map((n) => n * 2)
```

```ts
const total: number = x.reduce((a, b) => a + b, 0)
```

```rs
fn main() { println!("hi"); }
```
You get
js
const x = [1, 2, 3].map((n) => n * 2)
ts
const total: number = x.reduce((a, b) => a + b, 0)
rs
fn main() { println!("hi"); }

`js` and `javascript` are the same, as are `ts`/`typescript`, `py`/`python`, `rs`/`rust`, `sh`/`bash` and `yml`/`yaml`. Case does not matter.

Unknown languages do not break

Give a language that does not exist and the block still renders — it falls back to plain text rather than erroring or swallowing the rest of the document.

You write
```not-a-real-language
this block still renders
  with its indentation intact
```
You get
not-a-real-language
this block still renders  with its indentation intact

This matters more than it sounds. Plenty of tools break the whole page on an unrecognised identifier, which is a poor trade for a typo in a fence.

Fences inside fences

To show markdown that itself contains a code block, open the outer fence with more backticks than the inner one. Four outside, three inside.

You write
````markdown
Here is how you write a code block:

```js
const x = 1
```
````
You get
markdown
Here is how you write a code block:
```jsconst x = 1```

The rule is simply that the closing fence must be at least as long as the opening one, so a longer outer fence cannot be closed early by the inner block.

Inline code, and backticks inside it

Single backticks mark code inside a sentence. If the code itself contains a backtick, wrap it in two and pad with spaces.

You write
Run `npm install` to begin.

To show a backtick, write `` ` `` with double backticks.

The variable `user_name` keeps its underscores.
You get

Run npm install to begin.

To show a backtick, write ` with double backticks.

The variable user_name keeps its underscores.`

Underscores and asterisks inside inline code are literal, which is why `snake_case` survives intact instead of turning into italics.

Diffs

The `diff` language colours added and removed lines, which makes it the clearest way to show a change without screenshotting a pull request.

You write
```diff
 function greet(name) {
-  return "Hello, " + name
+  return `Hello, ${name}`
 }
```
You get
diff
 function greet(name) {-  return "Hello, " + name+  return `Hello, ${name}` }

Leading space for unchanged lines, minus for removed, plus for added. Paste the output of `git diff` and it will usually just work.

Indented blocks (the older style)

Four spaces of indentation also makes a code block. It predates fences and still works, but it cannot carry a language, so nothing is highlighted.

You write
A paragraph, then an indented block:

    $ cargo build --release
    Compiling markdownbin v0.1.0

Back to normal text.
You get

A paragraph, then an indented block:

$ cargo build --releaseCompiling markdownbin v0.1.0

Back to normal text.

Use fences instead unless you have a reason not to. Indented blocks are easy to trigger by accident when pasting already-indented text, which is a common cause of "why is my paragraph in a grey box".

Share code that stays readable

Paste a snippet, get a link that highlights it properly — no signup, and no paywall on the highlighting. Encrypt it if the contents should not be public.