Library
We create libraries for re-using in different places, projects, and by other people. The library's code is read more often than it's modified, simply because it's maintained by a limited number of people, whereas the number of users can be much higher. This is especially true for an open-source library. The library's code is consumed by a computer, but a person is the user and who interacts with it.
The layout of a library project should take these factors into account. This means that the layout needs to be optimised for interaction with the user, a person. We seek for answers in documentation, and read the code provided by a library to understand how it works. If a library is well-organised and neat, the process of using it smooth and unobtrusive.
So how can we make this interaction more positive from the layout perspective? If the Common guidelines are taken into account and implemented, that's mostly enough. They cover the most important aspects, and can and should be applied to a library project. Additionally, the following will help you in providing a better experience for the users of a library:
- providing a good README file
- keeping the number of files at the top level of a manageable size
- providing examples of using the library
- providing benchmarking information, if applicable
The rest of the section describes these suggestions in detail.
Provide a Good README File
Provide a well-organised README file with the most important information about the library.
The README file should give answers to the following questions:
- What is it? Provide a short description of the library. Ideally, one-two sentences.
- What does it do? Describe the problem the library is solving.
- Why does it exist? It should be clear why this library exists, especially if it's not the only library solving a particular problem. What does it do differently from others in its area?
- How does it solve the problem? Give the users an idea on what's going on under the hood, and what to expect from it.
In addition to the above, the README should contain links to related resources like:
- the GoDoc page
- any resources that describe details of algorithms or approaches taken in the library
- articles or other resources that might be related to the topic.
Your goal with the README file is to help your users in answering the most important question about the library: "Does it help me in solving my problem?". Even if a library does solve a hard problem in a great way, if it isn't reflected in the documentation, that might be unnoticed, thus leading to less people using the library. A well-prepared README file helps your users to answer their questions.
Keep the Top-Level List of a Manageable Size
Keep the root level list of files short and focused. While this sounds very similar to this guideline, it's worth a mention here.
Strive to keep the number of root elements such that it takes less than a full page height, so the user doesn't need to scroll to get to the README. It's also important when the user interacts with a library from their IDE. An endless list of files visually complicates navigation, and gives an impression of a poor organisation.
Additional recommendations will be given further in the unit about designing a good layout for a package.
Provide Examples
In the README, provide clear examples of using your library.
A user should not be forced to go to the GoDoc page, or consult with the code on what using the library looks like. Think about possible use cases, and provide appropriate examples that show it.
Pay special attention to how you're showing the use of the library. Write high-quality code as if it was production code. A half, if not more, of the users will copy and paste code from the examples as it is given. So make sure the examples are not misleading, and do not contain things that you wouldn't want to find in your own production codebase.
Follow these suggestions in order to provide your users with good and quality examples:
- handle errors properly instead of omitting them
- avoid globals as much as possible
- avoid using the
initfunction - use regular imports instead of dot-imports
- handle errors properly instead of instead of
panic-ing,log.Fatal-ing.
This is not an exhaustive list, and more detail will be given in the unit about writing good code. But this short list is enough to make examples better, as well as the code that your users write.
Provide Benchmarking Results
Provide benchmarks whenever possible.
When someone uses your library, it becomes part of their application. For those who do care about performance, it's important. Those who aren't interested in performance, will skip it. But those who are, will appreciate that. Oftentimes, performance is what differentiates one library from another, and the interested users would love to know about it.
Go provides us with all we need to write benchmarks, and to share the results with our users. So help your users in making the decision about the library, write and run benchmarks, and add the results to the README. Then, keep it up to date.
The suggestions given above are simple, yet not always easy to follow. Take the time, make sure the project is prepared and organised. Eventually, the users of the library will find it helpful, and they will thank you for having done this for them.
Examples
Below you can find some examples of well-prepared libraries, and a few that could have been organised better.
Good Examples
Can Be Improved
- lib/pq While the README lists some features, it doesn't answer many questions, nor it gives us examples of using it, benchmarks, or any other information about why should we use it. The file organisation could also be improved.
- go-redis/redis As the number of Redis clients is relatively high, it would be valuable to provide users with comparisons and benchmarks that show the difference from other packages. Also, the structure of the repository can be better as not everything need to live at the root level of the package.