Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Aug 21, 2022. It is now read-only.

💌 Things I've learned about writing good READMEs.

NotificationsYou must be signed in to change notification settings

hackergrrl/art-of-readme

Repository files navigation

This article can also be read inChinese,Japanese,Brazilian Portuguese,Spanish,German,French andTraditional Chinese.

Etymology

Where does the term "README" come from?

The nomenclature dates back toat least the 1970sand thePDP-10,though it may even harken back to the days of informative paper notes placed atopstacks of punchcards, "READ ME!" scrawled on them, describing their use.

A reader1 suggested that the title README may be a playful nudge toward LewisCarroll'sAlice's Adventures in Wonderland, which features a potion and a cakelabelled"DRINK ME" and"EAT ME", respectively.

The pattern of README appearing in all-caps is a consistent facet throughouthistory. In addition to the visual strikingness of using all-caps, UNIX systemswould sort capitals before lower case letters, conveniently putting the READMEbefore the rest of the directory's content2.

The intent is clear:"This is important information for the user to read beforeproceeding." Let's explore together what constitutes "important information" inthis modern age.

For creators, for consumers

This is an article about READMEs. About what they do, why they are an absolutenecessity, and how to craft them well.

This is written for module creators, for as a builder of modules, your job is tocreate something that will last. This is an inherent motivation, even if theauthor has no intent of sharing their work. Once 6 months pass, a module withoutdocumentation begins to look new and unfamiliar.

This is also written for module consumers, for every module author is also amodule consumer. Node has a very healthy degree of interdependency: no one livesat the bottom of the dependency tree.

Despite being focused on Node, the author contends that its lessons applyequally well to other programming ecosystems, as well.

Many modules: some good, some bad

The Node ecosystem is powered by its modules.npm is themagic that makes it allgo. In the course of a week, Node developers evaluatedozens of modules for inclusion in their projects. This is a great deal of powerbeing churned out on a daily basis, ripe for the plucking, just as fast as onecan writenpm install.

Like any ecosystem that is extremely accessible, the quality bar varies. npmdoes its best to nicely pack away all of these modules and ship them far andwide. However, the tools found are widely varied: some are shining and new,others broken and rusty, and still others are somewhere in between. There areeven some that we don't know what they do!

For modules, this can take the form of inaccurate or unhelpful names (anyguesses what thefudge module does?), no documentation, no tests, no sourcecode comments, or incomprehensible function names.

Many don't have an active maintainer. If a module has no human available toanswer questions and explain what a module does, combined with no remnants ofdocumentation left behind, a module becomes a bizarre alien artifact, unusableand incomprehensible by the archaeologist-hackers of tomorrow.

For those modules that do have documentation, where do they fall on the qualityspectrum? Maybe it's just a one-liner description:"sorts numbers by their hex value". Maybe it's a snippet of example code. These are both improvements uponnothing, but they tend to result in the worst-case scenario for a modern daymodule spelunker: digging into the source code to try and understand how itactually works. Writing excellent documentation is all about keeping the usersout of the source code by providing instructions sufficient to enjoy thewonderful abstractions that your module brings.

Node has a "wide" ecosystem: it's largely made up of a very long list ofindependent do-one-thing-well modules flying no flags but their own. There areexceptions, but despite these minor fiefdoms,it is the single-purpose commoners who, given their larger numbers, truly rule theNode kingdom.

This situation has a natural consequence: it can be hard to findquality modulesthat do exactly what you want.

This is okay. Truly. A low bar to entry and a discoverability problem isinfinitely better than a culture problem, where only the privileged few mayparticipate.

Plus, discoverability -- as it turns out -- is easier to address.

All roads lead to README.md

The Node community has responded to the challenge of discoverability indifferent ways.

Some experienced Node developers band together to createcuratedlists of quality modules.Developers leverage their many years examining hundreds of different modules toshare with newcomers thecrème de la crème: the best modules in each category.This might also take the form of RSS feeds and mailing lists of new modules deemedto be useful by trusted community members.

How about the social graph? This idea spurred the creation ofnode-modules.com, a npm search replacement thatleverages your GitHub social graph to find modules your friends like or havemade.

Of course there is also npm's built-insearchfunctionality: a safe default, and the usual port of entry for new developers.

No matter your approach, regardless whether a module spelunker enters the moduleunderground atnpmjs.org,github.com, or somewhere else, this would-be user willeventually end up staring your README square in the face. Since your userswill inevitably find themselves here, what can be done to make their firstimpressions maximally effective?

Professional module spelunking

The README: Your one-stop shop

A README is a module consumer's first -- and maybe only -- look into yourcreation. The consumer wants a module to fulfill their need, so you must explainexactly what need your module fills, and how effectively it does so.

Your job is to

  1. tell them what it is (with context)
  2. show them what it looks like in action
  3. show them how they use it
  4. tell them any other relevant details

This isyour job. It's up to the module creator to prove that their work is ashining gem in the sea of slipshod modules. Since so many developers' eyes willfind their way to your README before anything else, quality here is yourpublic-facing measure of your work.

Brevity

The lack of a README is a powerful red flag, but even a lengthy README is notindicative of there being high quality. The ideal README is as short as it canbe without being any shorter. Detailed documentation is good -- make separatepages for it! -- but keep your README succinct.

Learn from the past

It is said that those who do not study their history are doomed to make itsmistakes again. Developers have been writing documentation for quite some numberof years. It would be wasteful to not look back a little bit and see what peopledid right before Node.

Perl, for all of the flak it receives, is in some ways the spiritual grandparentof Node. Both are high-level scripting languages, adopt many UNIX idioms, fuelmuch of the internet, and both feature a wide module ecosystem.

It so turns out that themonks of the Perl communityindeed have a great deal of experience in writingqualityREADMEs. CPAN is awonderful resource that is worth reading through to learn more about a communitythat wrote consistently high-calibre documentation.

No README? No abstraction

No README means developers will need to delve into your code in order tounderstand it.

The Perl monks have wisdom to share on the matter:

Your documentation is complete when someone can use your module without everhaving to look at its code. This is very important. This makes it possible foryou to separate your module's documented interface from its internalimplementation (guts). This is good because it means that you are free tochange the module's internals as long as the interface remains the same.

Remember: the documentation, not the code, defines what a module does.--Ken Williams

Key elements

Once a README is located, the brave module spelunker must scan it to discern ifit matches the developer's needs. This becomes essentially a series of patternmatching problems for their brain to solve, where each step takes them deeperinto the module and its details.

Let's say, for example, my search for a 2D collision detection module leads metocollide-2d-aabb-aabb. Ibegin to examine it from top to bottom:

  1. Name -- self-explanatory names are best.collide-2d-aabb-aabb soundspromising, though it assumes I know what an "aabb" is. If the name sounds toovague or unrelated, it may be a signal to move on.

  2. One-liner -- having a one-liner that describes the module is useful forgetting an idea of what the module does in slightly greater detail.collide-2d-aabb-aabb says it

    Determines whether a moving axis-aligned bounding box (AABB) collides withother AABBs.

    Awesome: it defines what an AABB is, and what the module does. Now to gauge howwell it'd fit into my code:

  3. Usage -- rather than starting to delve into the API docs, it'd be great tosee what the module looks like in action. I can quickly determine whether theexample JS fits the desired style and problem. People have lots of opinionson things like promises/callbacks and ES6. If it does fit the bill, then Ican proceed to greater detail.

  4. API -- the name, description, and usage of this module all sound appealingto me. I'm very likely to use this module at this point. I just need to scanthe API to make sure it does exactly what I need and that it will integrateeasily into my codebase. The API section ought to detail the module's objectsand functions, their signatures, return types, callbacks, and events indetail. Types should be included where they aren't obvious. Caveats should bemade clear.

  5. Installation -- if I've read this far down, then I'm sold on trying out themodule. If there are nonstandard installation notes, here's where they'd go,but even if it's just a regularnpm install, I'd like to see that mentioned,too. New users start using Node all the time, so having a link to npmjs.organd an install command provides them the resources to figure out how Nodemodules work.

  6. License -- most modules put this at the very bottom, but this mightactually be better to have higher up; you're likely to exclude a module VERYquickly if it has a license incompatible with your work. I generally stick tothe MIT/BSD/X11/ISC flavours. If you have a non-permissive license, stick itat the very top of the module to prevent any confusion.

Cognitive funneling

The ordering of the above was not chosen at random.

Module consumers use many modules, and need to look at many modules.

Once you've looked at hundreds of modules, you begin to notice that the mindbenefits from predictable patterns.

You also start to build out your own personal heuristic for what information youwant, and what red flags disqualify modules quickly.

Thus, it follows that in a README it is desirable to have:

  1. a predictable format
  2. certain key elements present

You don't need to usethis format, but try to be consistent to save your usersprecious cognitive cycles.

The ordering presented here is lovingly referred to as "cognitive funneling,"and can be imagined as a funnel held upright, where the widest end contains thebroadest more pertinent details, and moving deeper down into the funnel presentsmore specific details that are pertinent for only a reader who is interestedenough in your work to have reached that deeply in the document. Finally, thebottom can be reserved for details only for those intrigued by the deepercontext of the work (background, credits, biblio, etc.).

Once again, the Perl monks have wisdom to share on the subject:

The level of detail in Perl module documentation generally goes fromless detailed to more detailed. Your SYNOPSIS section shouldcontain a minimal example of use (perhaps as little as one line ofcode; skip the unusual use cases or anything not needed by mostusers); the DESCRIPTION should describe your module in broad terms,generally in just a few paragraphs; more detail of the module'sroutines or methods, lengthy code examples, or other in-depthmaterial should be given in subsequent sections.

Ideally, someone who's slightly familiar with your module should beable to refresh their memory without hitting "page down". As yourreader continues through the document, they should receive aprogressively greater amount of knowledge.-- fromperlmodstyle

Care about people's time

Awesome; the ordering of these key elements should be decided by how quicklythey let someone 'short circuit' and bail on your module.

This sounds bleak, doesn't it? But think about it: your job, when you're doingit with optimal altruism in mind, isn't to "sell" people on your work. It's tolet them evaluate what your creation does as objectively as possible, and decidewhether it meets their needs or not -- not to, say, maximize your downloads oruserbase.

This mindset doesn't appeal to everyone; it requires checking your ego at thedoor and letting the work speak for itself as much as possible. Your only job isto describe its promise as succinctly as you can, so module spelunkers caneither use your work when it's a fit, or move on to something else that does.

Call to arms!

Go forth, brave module spelunker, and make your work discoverable and usablethrough excellent documentation!

Bonus: other good practices

Outside of the key points of the article, there are other practices you canfollow (or not follow) to raise your README's quality bar even further andmaximize its usefulness to others:

  1. Consider including aBackground section if your module depends onimportant but not widely known abstractions or other ecosystems. The functionofbisecting-between is notimmediately obvious from its name, so it has a detailedBackground sectionto define and link to the big concepts and abstractions one needs tounderstand to use and grok it. This is also a great place to explain themodule's motivation if similar modules already exist on npm.

  2. Aggressively linkify! If you talk about other modules, ideas, or people, makethat reference text a link so that visitors can more easily grok your moduleand the ideas it builds on. Few modules exist in a vacuum: all work comesfrom other work, so it pays to help users follow your module's history andinspiration.

  3. Include information on types of arguments and return parameters if it's notobvious. Prefer convention wherever possible (cb probably means callbackfunction,num probably means aNumber, etc.).

  4. Include the example code inUsage as a file in your repo -- maybe asexample.js. It's great to have README code that users can actually run ifthey clone the repository.

  5. Be judicious in your use of badges. They're easy toabuse. They can also be a breedingground for bikeshedding and endless debate. They add visual noise to yourREADME and generally only function if the user is reading your Markdown in abrowser online, since the images are often hosted elsewhere on theinternet. For each badge, consider: "what real value is this badge providingto the typical viewer of this README?" Do you have a CI badge to show build/teststatus? This signal would better reach important parties by emailingmaintainers or automatically creating an issue. Always consider theaudience of the data in your README and ask yourself if there's a flow forthat data that can better reach its intended audience.

  6. API formatting is highly bikesheddable. Use whatever format you think isclearest, but make sure your format expresses important subtleties:

    a. which parameters are optional, and their defaults

    b. type information, where it is not obvious from convention

    c. foropts object parameters, all keys and values that are accepted

    d. don't shy away from providing a tiny example of an API function's use ifit is not obvious or fully covered in theUsage section.However, this can also be a strong signal that the function is too complexand needs to be refactored, broken into smaller functions, or removedaltogether

    e. aggressively linkify specialized terminology! In markdown you can keepfootnotes atthe bottom of your document, so referring to them several times throughoutbecomes cheap. Some of my personal preferences on API formatting can befoundhere

  7. If your module is a small collection of stateless functions, having aUsage section as aNode REPLsession of functioncalls and results might communicate usage more clearly than a source codefile to run.

  8. If your module provides a CLI (command line interface) instead of (or inaddition to) a programmatic API, show usage examples as command invocationsand their output. If you create or modify a file,cat it to demonstratethe change before and after.

  9. Don't forget to usepackage.jsonkeywords to directmodule spelunkers to your doorstep.

  10. The more you change your API, the more work you need to exert updatingdocumentation -- the implication here is that you should keep your APIssmall and concretely defined early on. Requirements change over time, butinstead of front-loading assumptions into the APIs of your modules, loadthem up one level of abstraction: the module set itself. If the requirementsdo change and 'do-one-concrete-thing' no longer makes sense, then simplywrite a new module that does the thing you need. The 'do-one-concrete-thing'module remains a valid and valuable model for the npm ecosystem, and yourcourse correction cost you nothing but a simple substitution of one module foranother.

  11. Finally, please remember that your version control repository and itsembedded README will outlive yourrepository host andany of the things you hyperlink to -- especially images -- soinline anythingthat is essential to future users grokking your work.

Bonus:common-readme

Not coincidentally, this is also the format used bycommon-readme, a set of READMEguidelines and handy command-line generator. If you like what's written here,you may save some time writing READMEs withcommon-readme. You'll findreal module examples with this format, too.

You may also enjoystandard-readme, which is amore structured, lintable take on a common README format.

Bonus: Exemplars

Theory is well and good, but what do excellent READMEs look like? Here are somethat I think embody the principles of this article well:

Bonus: The README Checklist

A helpful checklist to gauge how your README is coming along:

  • One-liner explaining the purpose of the module
  • Necessary background context & links
  • Potentially unfamiliar terms link to informative sources
  • Clear,runnable example of usage
  • Installation instructions
  • Extensive API documentation
  • Performscognitive funneling
  • Caveats and limitations mentioned up-front
  • Doesn't rely on images to relay critical information
  • License

The author

Hi, I'mKira.

This little project began back in May in Berlin at squatconf, where I wasdigging into how Perl monks write their documentation and also lamenting thestate of READMEs in the Node ecosystem. It spurred me to createcommon-readme. The "README Tips"section overflowed with tips though, which I decided could be usefully collectedinto an article about writing READMEs. Thus, Art of README was born!

Further Reading

Footnotes

  1. Thanks,Sixes666!

  2. SeeThe Jargon File.However, most systems today will not sort capitals before all lowercasecharacters, reducing this convention's usefulness to just the visualstrikingness of all-caps.

Credits

A heartfelt thank you to@mafintosh and@feross for the encouragement I needed to get thisidea off the ground and start writing!

Thank you to the following awesome readers for noticing errors and sending mePRs ❤️ :

Thank you to@qihaiyan for translating Art ofREADME to Chinese! The following users also made contributions:

Thank you to@lennonjesus for translating Artof README to Brazilian Portuguese! The following users also made contributions:

Thank you to@jabiinfante for translating Artof README to Spanish!

Thank you to@Ryuno-Ki for translating Art ofREADME to German! The following users also made contributions:

Thank you to@Manfred Madelaine and@Ruben Madelainefor translating Art of README to French!

Other Resources

Some readers have suggested other useful resources for README composition:

License

Creative Commons Attribution License

About

💌 Things I've learned about writing good READMEs.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp