When it comes to writing documentation, it's not uncommon to hear people ask "what's the point?" There are several very good reasons for why you should write documentation:
- You have teammates that need to use your software. If there's no documentation, they won't know what to do.
- You will have to use your software in the future, probably after a long absence where you haven't looked at it. If there's no documentation, you won't know what to do.
- Writing a README forces you to think about your software from another person's perspective. This results in better-designed software (see README-driven Development).
- Some IDEs utilise the documentation for type hinting. This enables devs that utilise IDEs to be more productive.
Keep your documentation up to date and consistent. Incorrect documentation is actually worse than missing documentation; in both cases the user has to dive into the code to figure out how it works, but in the first case they've also wasted time trying to do something wrong and figuring out that it's the documentation that's wrong.
Generally you want both a guide and a reference. A guide is about conceptual examples, and usually serves as the introduction to a README or a reference. A reference (a.k.a. API documentation) should have every detail of your software documented in full.
For an example of a guide, see Express: Getting Started. For an example of a reference, see go-uuid. For an example of both together, see go-qml or go-sqlite.
What is the software for? What problem does it solve? What existing solutions solve this same problem, and what's the difference between your solution and existing ones? If applicable, a small example (10-20 lines) of how your software works can be better than paragraphs of text.
You should have instructions on how to install your software, as well as instructions on installing its dependencies. Try to assume that your user knows nothing; if your software runs on node, link to instructions on installing node.
You should always have instructions on how to run your test cases, because
- It means that you have tests.
- Clear test cases will make it easier for others to contribute to your software.
If your software is a service, you should have instructions on how to run it, as well as documentation about any command flags or environment variables that it uses.
If your software is a module or library, you should include a lot more information.
You can start with a variety of usage examples, showing the most common uses of your software. When someone is looking for a library to solve some problem, usage examples are the fastest way for them to know if your software solves their problem.
After that, you can get into more instructions on how to include it in another piece of software, as well as API documentation.
API documentation should include a description of each function, type, or interface that your library provides. Some API documentation may be autogenerated. For a good example of this, see godocdown and baseworker-go
Functions should document all of their arguments, as well as default arguments (if applicable). Where possible, you should also thoroughly document type information (even for dynamically typed languages). More complex functions should also include their own examples.
As much as we all wish it weren't the case, all software fails eventually. If there are common patterns for failure, you should document those and how to avoid them:
- Did you forget to install dependency ?
- Did you misconfigure the service?
- Are you using an old version of some dependency?
The changelog doesn't necessarily have to be in the README, you could just link to one (autogenerated based on Github releases?).
However, no matter how you do it, you should have one. Changelogs allow prospective users of your software to see how much it's changing and how actively it's developed. For existing users, it provides a convenient way for them to weigh the benefits of upgrading the version they're using to a new one.
Some documentation doesn't belong in the README. There are basically two types of people you want to have documentation for: people who want to use your software and people who want to contribute to your software.
The README mostly accommodates the first type of person, and because of this should be oblivious to implementation details of your software.
To accommodate the second person, you want comments within your code that explain potentially confusing/non-obvious code, as well as extensive test cases.
There should be as little overlap as possible between your README and your comments (unless your README is generated from your comments).
Ideally, each piece of information should be written in only once place. Otherwise, when that information changes, there are multiple places you need to update it, which very often leads to outdated documentation.
If you want information in more than one place, it should still only be written once, and then included in other places through some sort of templating library or document generation.
Tests should capture the full behavior of your software on all inputs. Docs should communicate the most common behavior of code (e.g. through short examples). You can then point to test cases for examples of uncommon usage of your software. Your documentation shouldn't drown the reader in a huge list of options ("do one thing and do it well").
- Write The Docs: A site dedicated to "the art of writing documentation."