Jeffrey Paul: README HOWTO

Jeffrey Paul

README HOWTO
24 December 2024
( 2470 words, approximately 13 minutes reading time. )

As a certified Hacker News addict (like Slashdot before it), I see a lot of open source projects get publicly announced.

The default entrypoint for information about your open source project is of course the README file. Code forges usually render it directly onto your repo’s main page, so it serves as sort of a secondary, mostly-text-only static webpage for your project.

Most of them that I see are startlingly bad because they are missing key data points about the project. Assuming knowledge about things in your reader that they don’t have displays a jarring lack of empathy. You’re really close to your project; most visitors to your README are being exposed to it for the first time and have zero context whatsoever.

Here’s an honest attempt at an all-inclusive list of dos and don’ts for your README. If I’ve missed any (or you’re mad about the ones I included and have something to useful to say other than “I’m mad”), email me: sneak@sneak.berlin.

Note that I break some of the rules in this HOWTO. This is a HOWTO and not a README, and the intended audience of a README is the general public, and the intended audience of this HOWTO is README authors. Additionally, these are guidelines, and your README isn’t going to be graded or judged. It’s not the end of the world if you don’t follow this document to the letter.

Do

Above The Fold

This is the stuff that should appear in the first ten or fifteen lines (as hard wrapped to no more than 80-100 cols) of your README.

  • Do include a short and complete description of the functionality and purpose of the software as the first line in the readme.
    • e.g. make is a command line tool for running builds based on a rules-based Makefile
  • Do hyperlink the first word (the name of your package) to its official website, even if it is the same repo page on which the README appears. This is because people might be cloning the repo and viewing the README in other contexts, or offline.
    • e.g. [make](https://www.gnu.org/software/make/)
  • Do include the primary programming language name in the first sentence description. Any tightly-coupled libraries (like React, for example) might also be good to mention.
    • e.g. written in C or written in [ES6](https://262.ecma-international.org/6.0/) and [JSX](https://facebook.github.io/jsx/) using [React](https://react.dev/)
    • Almost all projects forget to include this one, so don’t be that guy
  • Do include the license name in the first sentence description, and link to the license’s info page.
    • e.g. and released under the [GPL Version 3](https://opensource.org/license/gpl-3-0).
    • Almost all projects forget to include this one, and it’s mega important
    • Yes, the code forge site may display this next to the README, but the README isn’t always going to be read on the web or on that website.
  • Do include the approximate date of original release, as well as the current version and release date. There is a huge difference between a 0.0.9 that has been developed over the last 90 days, and a 9.7 of a project that has been actively developed for a decade.

  • If that programming language isn’t one of the top five or ten, put in a parenthetical reference that includes a 4-6 word description of the programming language. Link it!
    • e.g. written in [FooBaz](https://foobaz.example) (a $DESC programming language released in $ORIGINAL_RELEASE_DATE under $LICENSE)
    • e.g. written in [Julia](https://julialang.org) (a high-level dynamic programming language for scientific computing, first released in 2012 under the MIT license)
  • Do mention the name of the company, if this is a corporate project. Link the first appearance of the company name to the company’s official website.
    • e.g. developed by [FooCorp](https://foocorp.example) as part of a commercial service offering
  • Do mention the goals of the project. If it’s the result of a team of university staff under a grant, that’s a very different situation than a hobby weekend project by a lone wolf hacker scratching an itch.
    • e.g. to provide a simple, fast, and reliable way to manage dependencies in a large ES6 codebase
    • e.g. to efficiently ingest terabytes of sensor data collected from the experimental Foo reactor at the University of FooBar
  • Do make it clear who you envision the end user of the software to be. A command line helper app written by one person in a weekend that spits out fun emoji and a cloud-native API gateway proxy sidecar container that requires a working etcd cluster to start up are likely going to end up in daily use by very different types of users (or at least users using very different contexts).
    • e.g. for use by developers of large, complex, multi-language projects
    • e.g. for use by operators of large-scale Kubernetes clusters
    • e.g. for use by security administrators in regulated financial environments
  • Do make extensive use of hyperlinks; err on the side of too many if you aren’t sure. Link everything that can be linked in the first section; company names, library names, programming language names, license types, distributions, OSes, dependencies, file formats, standards documents, etc. If there isn’t an “official” site for the entity, link a Wikipedia article. Make it very easy for people to get additional context if they want it (or to ignore it if they don’t).
    • links in markdown are in brackets with the URL in trailing parentheses: [Go](https://golang.org)

Below The Fold

  • Do include the exact commands that one would need to copy and paste to build the project. Ideally this is only a few lines, as you’ve included build scripts or a Makefile or something in the repo. If you’re good, this is literally just the command make.

  • Do include the exact commands that one would need to copy and paste to install the build prerequisites on the most common distros. If your build system is anything other than make, that’s a dependency too and needs to be installed. Assume this is getting pasted into a completely fresh install VM.
    • e.g. apt-get install -y libfoo-dev libbar-dev libbaz3-dev cmake
  • Do mention whatever versioning scheme you use, whether SemVer or yyyymmdd.xx or yy.mm (like Ubuntu).

  • Do include usage/invocation examples (with corresponding output) if your project is small or simple.

  • Do include some text-based screenshots (<code> or <pre> blocks or triple-backticks in markdown) if applicable. Avoid graphical screenshots if it’s just text.

  • Do include the reason your project came into existence. You don’t need a whole brand story (unless you want to), just a sentence or two is fine.

  • Do include some information (including code examples) of any specialty programming language features or styles that your project focuses on. For example, if you are a functional programming library, show some common functional programming usage examples before and after your library so people can understand why you exist.

  • Do include a top level “Getting Started” section for first-time users. This should include a quickstart guide (possibly inline in the README, or a link to the appropriate subsection of documentation, a link to the full documentation, and a link to the community participation section.

Participation

  • Do include a top level “Authors” section that lists the names (or usernames) and email addresses of the maintainers or primary authors. Link to their personal pages/profiles if desired. Full names and websites are optional; email addresses are not. Try to make this reasonably complete, as it implicitly clarifies how big the management headcount of the project is.

  • Do include a top-level “Participation” section.

  • Do include an explanation of the contribution process. Do you want contributions at all? Do you want bug reports? Do you want them via email, or via GitHub issues? Do you accept pull requests? Can people who submit PRs reasonably expect them to be merged? As-is or with a round of review/requested changes? TELL US. Set expectations.

  • Do include a complete list of any contribution hard requirements. Link to code style guidelines or linting configuration that must pass.

  • Do be extremely clear if a Contributor License Agreement (CLA) or other legal document is required to contribute.

  • If you do have a requisite legal document for contributions, mention in the README if if it requires copyright assignment. A developer certificate of origin to cover your ass is one thing; a CLA assigning ownership to the sponsoring organization for dual-licensing as nonfree software is a horse of a different color.
    • eg: Contributions to this project are managed by $COMPANYNAME and contributors must sign a Contributor License Agreement (CLA) and copyright assignment to be included so that $COMPANYNAME may dual-license this software.
    • eg: Contributions to this project are managed by $COMPANYNAME and contributors must license their contributions under the same $LICENSENAME license as the project and provide a signed Developer Certificate of Origin to $COMPANYNAME to be included.
  • Do use your README as the authoritative documentation of the complete list of venues for collaboration. List and link every place your community communes: bug tracker (even if on the same site), wiki, socials, subreddits, forums, irc channels, slack groups, discords, matrix rooms, activitypub, mailing lists, everything. Feel free to bias the list sorting to steer participants to preferred/popular venues.

Ideology

  • Do make it clear what sort of community participants can expect. If you have a Code of Conduct, link it and list it by name if it’s a standard one. If you don’t have one, mention that too. Be transparent so that people can make informed decisions about participation.

  • Do make it clear if the project exists primarily as a tool for a for-profit company, such as the so-called “open core” offerring of a startup. You aren’t the Apache Software Foundation or GNU because you used VC money to build and release an MIT-licensed enterprise tool that gates SSO or audit features behind a dual-licensing paywall; be clear about who and what you are so people have context.

  • Do make it clear if your project is one free software component of a larger system that includes nonfree software, or vice versa.

  • Do make it clear if your project/software primarily exists to interface with a single centralized service, and link to that service and ideally also its EULA or TOS.

  • Do make it abundantly clear if the software is going to transmit user activity data off of the device on which it is run. Link to the associated privacy policy, if so. (Better yet, just don’t do that, so you don’t have to warn users in advance that you publish shady software.)

Don’t

  • Don’t assume your above-the-fold README audience has ever heard of you, your project, or your favorite new language obsession du jour.

  • Don’t assume that the reader knows industry/specialty jargon. It’s ok to get technical (or make your README big) but the audience is the general web-using public. It’s ok to get as opaque and obscure as you wish in the primary technical documentation, but the README generally isn’t that. It’s an introduction, with pointers to more in-depth docs.

  • Don’t use acronyms, initialisms, or abbreviations in the document without expanding them at least once at the first use. If it’s not onerous or obnoxious, just use the expanded versions exclusively instead of the acronyms or initialisms.

  • Don’t worry about your README getting too big as long as you have good section headings. If any sections get too big, you can always factor them out later to other files if necessary (and replace them with a link to that other file), but “too big” is quite big, as vertical scrolling is cheap. It’s entirely ok for your README to contain all of the primary documentation (as well as everything else listed here) for a small project.

  • Don’t obfuscate email addresses; write them correctly and in full and linkify them and make them clickable via mailto: URLs. It’s totally ineffective anyway; spammers and web crawlers know how to use regex too. The web is not the place to fight email spam, it’s in your email and network infrastructure. All it does is make it so legitimate users can’t one-click contact you, with no other benefit.

  • Don’t leave issues open if you don’t want bug reports.

  • Don’t invite bug reports if you aren’t willing to engage with them.

  • Don’t auto-close bugs for “inactivity”. This is a slap in the face to the reporters, who spent time and effort to deliver them to you. Auto-closing their reports is the same as throwing a gift in the trash in front of the giver.

  • Don’t host your README (or your project) on GitHub, which is owned by Microsoft and collaborates with operators of concentration camps. Microsoft is still the same evil empire military-industrial complex bullshit they were in the 90s, they’re just much richer and have better PR now to manipulate you into liking them. They don’t believe in software freedoms, they don’t believe in free software (despite releasing some software under free software licenses as cosplay), and they don’t want a world in which free software that respects user freedoms and privacy displaces proprietary surveillanceware. (A quick look at VS Code or Windows or WSL confirms this.) Don’t send eyeballs or traffic to their domain names or subsidiaries.

  • Don’t succumb to the draw of centralized, censored, surveillance collaboration tools like Discord (or, again, GitHub) for your project. These are exclusionary (try using them via Tor or without a phone number on a VPN) and discriminate against those who need to preserve their privacy, and you should aim to not discriminate unnecessarily against potential participants.

Example Document

I have updated the README of my hobby project mfer to reflect these guidelines. You can view mfer project’s README file at:

https://git.eeqj.de/sneak/mfer/src/branch/main/README.md

Discussion

This, as all posts, can be discussed on the BBS.

About The Author

Jeffrey Paul is a hacker and security researcher living in Berlin and the founder of EEQJ, a consulting and research organization.

 sneak@sneak.berlin

 @sneak@sneak.berlin

 @sneakdotberlin

 @eeqj

 linkedin.com/in/jeffreypauleeqj