Blog
4 min read

The anatomy of a great README

Your README is the front door to your project. What every great one should include.

best-practicesdocumentationopen-source

Your README is the front door to your project. It’s the first thing developers see when they land on your repository, and it shapes their entire first impression. A well-crafted README can mean the difference between someone diving into your project or bouncing to find an alternative.

Here’s what every great README should cover:

The specific sections you need will vary. Application READMEs look different from library READMEs. Private projects have different needs than open source ones. Use the sections that make sense for your project.

Overview

Why does this project exist?

Keep this short—a paragraph or two at most. Explain the project’s purpose at a high level so that someone with zero context can quickly understand what they’re looking at.

You don’t need to tell the entire origin story or dive into implementation details. Just answer the fundamental question: why does this exist? For libraries, explain why someone would choose this over alternatives.

Prerequisites

What do I need installed before I can run this?

List the software dependencies someone needs on a fresh machine. Include version requirements where they matter, but don’t go overboard with patch versions unless you have a specific reason.

Typical prerequisites include:

  • Languages and runtimes (Python 3.11, Node 20, PHP 8.3)
  • Databases (PostgreSQL 15, MySQL 8.0, Redis 7)
  • Package managers and build tools (Composer 2, pnpm, Cargo)

If your project uses a package manager like Composer or npm, specify the package manager version but skip listing individual packages—those are handled by your lock files.

Setup

How do I get this running on my machine?

Walk through the steps to install and configure the project. Don’t duplicate the installation instructions for prerequisites; assume those are already handled.

Include the actual shell commands. New contributors shouldn’t have to guess what install dependencies means when you could just write npm install.

If you’ve abstracted setup into a script, document how to run it:

./bin/setup

End with verification steps. How does someone know the setup worked? Maybe it’s visiting http://localhost:3000 or running ./bin/test. If there are common gotchas, mention them here so newcomers aren’t blindsided.

Usage

How do I actually use this thing?

This section matters most for libraries. If you’ve built an API client, show how to initialize it, configure authentication, and make a few representative calls:

from mylib import Client

client = Client(api_key="your-key")
response = client.users.list()

For applications, usage instructions are often unnecessary—users interact with the UI, not the README. Skip this section if it doesn’t add value.

Deploying

How do I ship changes to production?

Document the exact workflow for pushing changes to each environment. Don’t make people guess or dig through CI configs.

This might include:

  • Which branch triggers deployments
  • Any manual steps (asset compilation, migrations)
  • SSH access or deployment commands
  • How staging differs from production

Libraries typically skip this section since they’re consumed by other projects that have their own deployment processes.

Contributing

How can I help improve this project?

Explain what contributors need to know:

  • Where to submit changes (usually a pull request)
  • How to run the test suite
  • Any coding standards or conventions to follow
  • Who reviews and merges contributions

This section is especially important for open source projects or internal libraries used across multiple teams. For a small internal application maintained by one team, you might skip it entirely.

Reporting Bugs

Something’s broken. Now what?

Tell people how to report issues effectively. If you need specific information to troubleshoot—stack traces, screenshots, reproduction steps—say so upfront. The goal is reducing back-and-forth between reporters and maintainers.

For open source projects, link to GitHub Issues. For internal projects, point to your issue tracker.

If security vulnerabilities require special handling, provide a separate disclosure process. You probably don’t want critical security issues filed as public GitHub issues.

License

Can I actually use this?

For private projects, a simple note that the code is proprietary is fine.

For open source projects, this section is non-negotiable. Many developers won’t touch unlicensed code, and others avoid specific licenses that conflict with their needs.

The MIT License is a solid default for its simplicity and permissiveness. But the right license depends on your goals—check out Choose a License if you’re unsure.

Final thoughts

You don’t need every section for every project. A small utility script might only need an overview and usage example. A complex application might need all of these plus additional sections for architecture decisions or API documentation.

The point isn’t to check boxes. It’s to give people what they need to understand, use, and contribute to your project. When in doubt, imagine yourself six months from now, returning to this project with zero context. What would you want to know?