Mastering Markdown: The Complete Guide for Developers

CodeKit
markdowndocumentationgfm

What is Markdown?

Markdown is a lightweight markup language created by John Gruber in 2004. Its philosophy is simple: write in a format that’s readable as plain text and convertible to HTML. Unlike rich-text editors that hide formatting behind buttons, Markdown keeps the syntax visible and minimal—so you can focus on content rather than wrestling with formatting menus.

Today, Markdown is everywhere. GitHub READMEs, documentation sites, static site generators, note-taking apps, and even chat platforms like Slack and Discord all support Markdown. If you write for the web, you need to know Markdown.

You can preview your Markdown in real time with the Markdown Previewer on CodeKit.

Core Syntax

Headings

Use hash symbols for headings. The number of hashes corresponds to the heading level:

# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6

Paragraphs and Line Breaks

A blank line creates a paragraph. For a line break within a paragraph, end the line with two spaces or use <br>.

This is the first paragraph.

This is the second paragraph.

This line ends with two spaces.
This appears on the next line.

Emphasis

*italic* or _italic_
**bold** or __bold__
***bold and italic***
~~strikethrough~~ (GFM extension)

Lists

Unordered lists use -, *, or +:

- First item
- Second item
  - Nested item
  - Another nested item
- Third item

Ordered lists use numbers:

1. First step
2. Second step
3. Third step

You can also start a list at an arbitrary number by changing the first number—subsequent items auto-increment.

[Link text](https://example.com)
[Link with title](https://example.com "Hover text")

![Alt text](image.png)
![Alt text with title](image.png "Image title")

Reference-style links keep your text clean:

Check out the [documentation][docs] for more details.

[docs]: https://example.com/docs

Blockquotes

> This is a blockquote.
>
> It can span multiple paragraphs.
>
> > And even be nested.

Horizontal Rules

Three or more hyphens, asterisks, or underscores create a horizontal rule:

---
***
___

GitHub-Flavored Markdown (GFM) Extensions

GitHub-Flavored Markdown extends the original specification with features that developers use daily. Most modern Markdown parsers support GFM.

Tables

Tables are one of the most useful GFM additions:

| Feature       | Supported | Notes              |
|---------------|-----------|--------------------|
| Tables        | Yes       | GFM extension      |
| Task lists    | Yes       | GFM extension      |
| Strikethrough | Yes       | GFM extension      |
| Footnotes     | Varies    | Not in core GFM    |

Alignment is controlled with colons in the separator row:

| Left-aligned | Center-aligned | Right-aligned |
|:-------------|:--------------:|--------------:|
| Left         | Center         | Right         |

You don’t need to align the pipes perfectly—the rendered output is the same regardless of spacing. But aligning columns in your source makes the raw Markdown easier to read.

Task Lists

Task lists turn your Markdown into interactive checklists on GitHub:

- [x] Set up project structure
- [x] Write API endpoints
- [ ] Add authentication
- [ ] Deploy to production

Strikethrough

This text is ~~no longer relevant~~ replaced with new information.

GFM automatically converts URLs into clickable links without requiring the [text](url) syntax:

Visit https://codekit.dev for developer tools.

Disallowed Raw HTML

For security, GFM filters certain HTML tags like <script>, <textarea>, and <style> from rendered output. This prevents cross-site scripting in user-generated content.

Code Blocks

Inline Code

Wrap text in backticks for inline code:

Use the `console.log()` function to debug.

Fenced Code Blocks

Triple backticks create fenced code blocks. Add a language identifier for syntax highlighting:

```javascript
function greet(name) {
  return `Hello, ${name}!`;
}

console.log(greet('World'));
```

Supported Language Identifiers

Common identifiers include javascript, python, ruby, go, rust, java, bash, sql, json, yaml, html, css, typescript, cpp, and csharp. Most highlighters support hundreds of languages and aliases.

Indented Code Blocks

You can also indent code by four spaces or one tab, but fenced blocks are preferred because they support syntax highlighting and are less ambiguous:

    function hello() {
        return "world";
    }

Best Practices for Writing Markdown

1. Keep Line Length Reasonable

Long lines are hard to read in plain text and difficult to diff in version control. Break paragraphs at around 80–100 characters. Most editors can display a ruler at a specific column.

2. Use ATX-Style Headings

Prefer # Heading over Setext-style headings (underlining with === or ---). ATX headings are consistent, support all six levels, and are easier to search for.

3. Be Consistent with List Markers

Pick one unordered list marker (- is the most common) and stick with it throughout a document. Mixing -, *, and + in the same file creates visual noise.

4. Leave Blank Lines Around Structural Elements

Always add blank lines before and after headings, lists, code blocks, and blockquotes. Some parsers will break if you don’t:

<!-- Good -->
## Section

- Item one
- Item two

<!-- Bad (may not render correctly) -->
## Section
- Item one
- Item two

When a document has many links, reference-style definitions keep the text readable:

Check out the [API reference][api] and [style guide][style].

[api]: https://example.com/api
[style]: https://example.com/style

6. Prefer Fenced Code Blocks

Fenced blocks are unambiguous and support language hints. Indented code blocks can accidentally trigger when you indent regular text by four spaces.

7. Don’t Rely on HTML

While Markdown supports inline HTML, avoid it when a Markdown equivalent exists. HTML breaks portability—some renderers strip it, and it makes the source harder to read for people unfamiliar with HTML.

Advanced Techniques

Nested Structures

You can nest most Markdown elements inside other elements. Lists can contain code blocks, blockquotes, and even other lists:

1. Install the package:

   ```bash
   npm install my-package
  1. Configure the settings:

    Make sure to update the API key before deploying.

  2. Run the server:

    npm start

### Escaping Characters

If you need a literal character that Markdown would otherwise interpret as syntax, escape it with a backslash:

```markdown
\*This is not italic\*
\# This is not a heading

Characters you may need to escape: \, `, *, _, {, }, [, ], (, ), #, +, -, ., !, |.

Common Pitfalls

  • Missing blank lines: Forgetting blank lines before lists or code blocks is the most common reason Markdown doesn’t render as expected.
  • Inconsistent indentation: Nested lists require consistent indentation (2 or 4 spaces—pick one and stay consistent).
  • Trailing whitespace: Some editors trim trailing spaces, which breaks line breaks that rely on the two-space convention.
  • HTML inside code blocks: Fenced code blocks display HTML literally—no need to escape angle brackets.

Conclusion

Markdown is one of those tools that seems simple on the surface but rewards deeper study. The core syntax covers most everyday needs, and GFM extensions add the table and task list support that make Markdown viable for technical documentation. By following consistent conventions and understanding how parsers handle edge cases, you can write Markdown that’s clean, portable, and a pleasure to read—both as raw text and rendered HTML.

Ready to practice? Open the Markdown Previewer on CodeKit to write and preview Markdown side by side, with full GFM support and syntax highlighting.