Introduction

You may or may not have heard the term markdown before, but you've almost certainly come across it if you've been on the internet for longer than 10 minutes in the past year. Markdown is everywhere these days. Pretty much everyone writing content on the web these days is using or has used markdown for some project or another. And chatbots like ChatGPT, Claude, Gemini, etc. respond in markdown most of the time (that's how they get the bold headings, put items in lists, and all that fancy formatting stuff).

For me, I've used it on and off, but have always just preferred to write directly in HTML wherever possible. HTML is more flexible, and it's used way more in my line of work (software engineering — no surprise there, right?). But, I've recently wanted to start building out a "second brain" between this website and GitHub, and GitHub uses a markdown-first approach to its README files. So, it's time for me to finally get good at markdown.

Basic Syntax

Markdown is designed to be readable as plain text and render into clean HTML. Here are the core elements you'll use constantly.

Headings

Prefix a line with one or more # characters. The number of #s sets the heading level (H1 through H6):

# H1 — page or document title
## H2 — major section
### H3 — subsection
#### H4, ##### H5, ###### H6 — used sparingly

Bold and italic

Wrap text in asterisks or underscores to add emphasis:

**bold text**         or   __bold text__
*italic text*         or   _italic text_
***bold and italic*** or   ___bold and italic___

Lists

Use -, +, or * for unordered lists. For ordered lists, start each line with a number followed by a period — the actual numbers don't have to be sequential, the renderer will count for you:

- Apples
- Bananas
- Oranges

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

To nest a list, indent the child items far enough to clear the parent marker — at least past the first character of the parent item's text. In practice, 3–4 spaces is safe across parsers.

Links and images

Links use the format [link text](url). Images are the same but prefixed with !:

[GitHub](https://github.com)
![Alt text for the image](./path/to/image.png)

Code

Wrap inline code in single backticks: `variableName`. For a multi-line code block, use triple backticks and optionally specify the language for syntax highlighting:

```javascript
const greeting = "hello";
console.log(greeting);
```

Blockquotes

Prefix a line with > to create a blockquote. These are great for calling out notes or quoting source material:

> This is a blockquote.
> It can span multiple lines.

Horizontal rules

Three or more hyphens, asterisks, or underscores on their own line produce a horizontal divider:

---

Tables

Tables are a GitHub Flavored Markdown extension (not in the original spec), but they're supported everywhere you'll typically write — GitHub, VS Code, most documentation tools. They use pipes (|) to separate columns and a row of dashes to define the header:

| Name  | Role      |
|-------|-----------|
| Alice | Engineer  |
| Bob   | Designer  |

Colons in the divider row control alignment: :--- left, ---: right, :---: center.

Tips & Tricks I've picked up

Structure first

Use headers (#, ##, ###) to organize content hierarchically. Readers and parsers both benefit from clear structure.

Emphasis sparingly

Use **bold** for genuinely important terms and *italic* for titles or light emphasis. Overusing them dilutes their effect.

Lists for scannable content

Unordered lists (- or *) for items without order; numbered lists (1.) for steps or rankings.

Code formatting

Inline backticks for code, variables, or commands. Triple backticks with a language tag for blocks:

```python
print("hello")
```

Use links cleanly

[link text](url) keeps prose readable. Avoid raw URLs in body text.

Line breaks

A blank line creates a new paragraph. A single newline often doesn't render as a break, depending on the parser.

Keep it readable as plain text

Good Markdown looks decent even unrendered. If it feels cluttered with symbols, simplify.

Consistency

Pick one style for lists, headers, and emphasis and stick with it throughout a document.

What makes a good README ?

With the general tips and tricks out of the way, it's good to know some best practices for README's specifically. This is what I'm planning on writing most in markdown, so it was a heavy focus for me. Here are some things I found in my research.

Lead with clarity

Your first paragraph should answer "what is this and why does it matter?" in 2–3 sentences. No jargon, no assumed context.

Badge line

Right after the title, a row of shields.io badges (build status, license, version) signals a maintained project at a glance.

Standard section expectations

Most people expect certain things to appear in a certain order in readmes. That order is:

  1. Title + one-liner description
  2. Badges
  3. Screenshot or demo GIF (if applicable — hugely effective)
  4. Features (brief bullet list)
  5. Installation
  6. Usage (with real code examples)
  7. Configuration (if complex)
  8. Contributing
  9. License

Code blocks are critical

Every install command and usage example should be in a fenced code block with the language tagged. Copy-paste friction kills adoption.

Use relative links

Link to other files in your repo ([Contributing](./CONTRIBUTING.md)) rather than absolute URLs so they work across forks and branches.

Keep the tone direct

Write imperatives: "Install the package", "Run the server", not "You will need to install..."

Combining this into a pretty decent readme template (so I don't have to start from scratch every time)

    
        # Project Name

        > One-line description of what this does and who it's for.

        ![build](https://img.shields.io/github/actions/workflow/status/username/repo/ci.yml)
        ![license](https://img.shields.io/github/license/username/repo)
        ![version](https://img.shields.io/github/v/release/username/repo)

        ![Demo or screenshot](./docs/demo.gif)

        ## Features

        - Does X really well
        - Supports Y and Z
        - Fast, lightweight, no dependencies

        ## Installation

        **Prerequisites:** Node.js 18+, npm

        ```bash
        npm install your-package
        ```

        Verify it worked:

        ```bash
        your-package --version
        ```

        ## Usage

        ```javascript
        import { thing } from 'your-package';

        const result = thing({ option: true });
        console.log(result);
        ```

        Common use case example here — show a real, practical snippet.

        ## Configuration

        | Option | Type | Default | Description |
        |--------|------|---------|-------------|
        | `port` | number | `3000` | Port to listen on |
        | `debug` | boolean | `false` | Enable verbose logging |

        ## Contributing

        Contributions are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.

        ## License

        [MIT](./LICENSE)