Back to blog
4 min read

README Best Practices: What Every Open Source Project Needs

Your README is the front door to your project. Here's how to write one that makes developers want to use your tool.

Your README is the most important file in your repository. It is the first thing anyone sees when they find your project, and it is the page that determines whether they stick around or close the tab. A bad README kills adoption. A good one drives it.

Here is how to write a README that works.

Start With What It Does

The first two sentences of your README should tell the reader what your project is and what problem it solves. Not how it works. Not what inspired it. What it does.

Bad:

FooLib is a next-generation, highly performant, isomorphic JavaScript library built on top of modern web standards.

Good:

FooLib validates form data on the client and server using the same schema. Define your validation rules once and use them everywhere.

The reader should understand the value proposition within ten seconds. If they have to scroll past badges, a logo, a table of contents, and a features list just to learn what your project does, you have already lost most of them.

Show a Real Example Early

After explaining what the project does, show code. Not a list of features. Not a comparison table. A working code example that demonstrates the core use case.

import { schema, validate } from "foolib";

const userSchema = schema({
  name: "string",
  email: "email",
  age: "number|min:0",
});

const result = validate(userSchema, {
  name: "Alex",
  email: "alex@example.com",
  age: 28,
});

console.log(result.valid); // true

This example does three things. It shows the import style, so the reader knows whether it is CommonJS or ESM. It shows the API surface, so the reader knows whether the library is simple or complex. And it shows the output, so the reader knows what to expect.

Put this example within the first screenful of the README. Do not make people scroll for it.

Installation Must Be Copy-Paste

Your installation section should contain a single command that works. If you support multiple package managers, list them:

npm install foolib
# or
yarn add foolib
# or
pnpm add foolib

If your project requires additional setup — environment variables, database migrations, config files — list those steps right here, not in a separate page that the reader has to find.

Feature Lists Should Be Short

If you have a features section, keep it to five or six bullet points. Each one should be a concrete capability, not marketing language.

Bad features list:

  • Blazing fast
  • Developer-friendly API
  • Battle-tested in production
  • Extensible plugin system
  • First-class TypeScript support

Good features list:

  • Validates objects, arrays, and nested schemas
  • Runs in Node.js, Deno, and the browser
  • Custom error messages per field
  • Async validation with external lookups
  • 4 KB gzipped, zero dependencies

The difference is specificity. Every project claims to be fast and developer-friendly. Tell the reader what your project actually does that others don't.

Document the API Surface

Your README does not need to document every function, but it should cover the primary API. If your library exports five functions, show each one with a one-line description and a minimal example. If it exports fifty, summarize the main ones and link to full docs.

### `validate(schema, data)`

Validates `data` against a `schema`. Returns a result object
with `valid` (boolean) and `errors` (array).

### `schema(definition)`

Creates a reusable schema from a definition object.
Supports nested schemas via the `schema()` type.

This level of documentation — function name, parameters, one-line behavior — is the minimum. Anything less forces the reader to read your source code, and most of them will not bother.

Include a Contributing Section

If you want contributions, tell people how to contribute. Be specific:

## Contributing

1. Fork the repo and create a branch from `main`
2. Run `npm install` to install dependencies
3. Run `npm test` to make sure everything passes
4. Make your changes and add tests
5. Open a pull request

Also mention your code style, testing expectations, and how long it usually takes you to review PRs. Contributors want to know what they are signing up for.

License and Badges

Put the license at the bottom. Use a standard SPDX identifier and link to the full file:

## License

MIT — see [LICENSE](./LICENSE) for details.

As for badges — build status, npm version, coverage — keep them minimal. Two or three badges at the top of the README can be useful. A wall of fifteen badges is noise. The reader does not care about your code climate score; they care about whether your project works.

Common Mistakes

Assuming context. Your README is read by people who have never heard of your project. Don't assume they know what problem you solve, what ecosystem you belong to, or what alternatives exist.

Burying the example. If your first code example is below the fold, move it up. Code speaks louder than descriptions.

Over-documenting in the README. If your README is over 500 lines, it probably needs to be split into separate doc pages. The README should cover: what it is, how to install it, how to use it, and where to learn more.

Forgetting to update it. A README that documents last year's API is worse than no README at all. Treat it like code — review it in PRs, test the examples, keep it current.

The Bottom Line

A great README answers four questions: What is this? How do I install it? How do I use it? Where do I learn more? Answer those clearly and concisely, with real code examples, and you will have a README that outperforms the majority of open source projects.