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.
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
.
make is a command line tool for running builds based on a rules-based Makefile
README
appears. This is because people might be cloning the repo and viewing the README
in other contexts, or offline. [make](https://www.gnu.org/software/make/)
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/)
and released under the [GPL Version 3](https://opensource.org/license/gpl-3-0)
.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.
written in [FooBaz](https://foobaz.example) (a $DESC programming language released in $ORIGINAL_RELEASE_DATE under $LICENSE)
written in [Julia](https://julialang.org) (a high-level dynamic programming language for scientific computing, first released in 2012 under the MIT license)
developed by [FooCorp](https://foocorp.example) as part of a commercial service offering
to provide a simple, fast, and reliable way to manage dependencies in a large ES6 codebase
to efficiently ingest terabytes of sensor data collected from the experimental Foo reactor at the University of FooBar
for use by developers of large, complex, multi-language projects
for use by operators of large-scale Kubernetes clusters
for use by security administrators in regulated financial environments
[Go](https://golang.org)
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
.
make
, that’s a dependency too and needs to be installed. Assume this is getting pasted into a completely fresh install VM. 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.
README
, or a link to the appropriate subsection of documentation, a link to the full documentation, and a link to the community participation section.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.
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.
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.
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.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 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.
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
This, as all posts, can be discussed on the BBS.
Jeffrey Paul is a hacker and security researcher living in Berlin and the founder of EEQJ, a consulting and research organization.