Ask HN: How do you organize software documentation at work?
Recently I have ventured into technical writing. At the company I work for, documentation is scattered around ~4 different tools.
1. Google Docs 2. Confluence 3. GitHub (READMEs) 4. Slack
Each of those serves a purpose of course, Google Docs are very collaborative, Confluence is our source of truth, GitHub is mostly for engineering and finally Slack usually has some threads you can find if you run into certain issues.
I am not suggesting we should put all of this into a single tool, but I am wondering if there is a methodology for organizing documentation. I am aware of Diataxis, and want us to use this for certain services / products. What I am looking for in this ASK HN post though, is an overarching methodology of organizing all documentation.
92 comments
[ 4.8 ms ] story [ 180 ms ] threadI prefer two types of documentation:
1. Executable documentation - tests, asserts, even things like Jupyter notebooks that can be tested and executed
2. Timestamped documentation - documentation that has a clear date on it of when it was valid. So the reader has an expectation "This was true at X date, but may not be true now". This includes detailed pull requests and git commit messages.
https://softwaredoug.com/blog/2023/10/13/fight-undead-docume...
The documentation lives in the same git repository as the code that it documents.
Inaccuracies or out-of-date documentation is treated as a severe bug. Issues are filed, the documentation gets fixed.
This is crucial, because if zombie documentation is allowed to persist it causes people to lose trust in the documentation, which means they won't refer to it and they won't contribute to it.
Once the documentation is in a trustworthy state, keeping it that way gets a LOT easier. It becomes part of the code review process - a PR won't be accepted unless it updates the relevant documentation that accompanies the code change.
I've been using this policy for my own projects for quite a few years now, and the result is that I'm proud of the state of my documentation for almost the first time in my entire career.
1) LLM scans code updates and approximates output 2) Developer reviews and updates if needed 3) Feed back tagged code and updated output to LLM 4) ? 5) Profit
I think it basically came down to incentives. Those who were developing the code every day had all the relevant details in their heads. So ensuring that docs matched the code was basically a distraction from their primary goals.
It makes me a little angry because it screws over users of the software. The docs don't even mention that they might be out of date.
Why does this work with Git but not with non-Git? Being in Git doesn't seem to relevant to raising documentation bugs as bugs.
There are a bunch of other reasons to keep documentation in git. The most important is that it gives you versioned documentation that matches your releases - if someone is running v2.3 of your software they can browse the documentation for that exact version using that tag on GitHub.
If your documentation lives in some other system it can only ever attempt to be accurate for whatever the most recent release is. This is bad for people running older versions, and also makes it harder to develop documentation for unreleased code in a way that isn't potentially confusing.
My response is almost "too bad". :) Keeping things documented is part of the work, and if it isn't done, then the work is not completed.
Your suggestions of (1) and (2) are great suggestions to have as components to the documentation system. Notebooks are really fantastic for this.
Absolutely. Part of reviewing is checking that the eg. README is up to date and works as expected.
Bakes into your existing workflows, direct line of accountability to both the code reviewer and the dev.
The editing software can be anything really.
Especially if making changes to the over all architecture or introducing a new dependency! The team shouldn’t let the PR ,edge until the docs are sufficient
There may be longer write-ups, examples, etc. at the module level.
Documentation gets compiled into a docs.rs-style searchable website like so:
https://docs.rs/tokio/1.36.0/tokio/
Examples are compiled and run as part of the default CI toolchain.
So when a piece of documentation refers to some code that was moved or renamed, it is a bug to not update references in Rustdoc comments.
Comments can still get stale because some programmers write but don't read.
But they're right there on your screen next to the code you're updating.
How do you deal with cross-cutting concerns, docs that span multiple code repositories?
> some poor soul comes along and asks a question that's 5 years out of date because they found it on the wiki
This happens if there's docs in a git repo as well.
https://fossil-scm.org
Throwing your own other comment back at ya :D
If docs aren't maintained and curated then it doesn't matter if they are in a wiki, word docs, printed pages in a file cabinet or in the repository as markdown files. Getting team discipline around updating docs is the solution, the place where they are stored is sort of trivial if that discipline exists (fwiw, I've yet to see that discipline).
With that said, there are times where docs in source control are totally viable, especially when their scoped to the repo they are located in.
Dokuwiki for example has a sane, plain text format. It can be extended relatively easily compared to Confluence (I have tried both).
Unlike certain other wikis it has access control and unlike Confluence you can edit a single paragraph or section at a time.
And finally, it is actually a wiki, wiki originally meant "quick" I think and I think calling Confluence a wiki in that context is somewhat ironic.
For example, a development setup at a company or group may require a certain setup that depends upon the operating system and IDE/editor an individual developer uses. This type of information is perfect to put on wikis. It is effectively "global" information, whereas repositories contain local information. Putting information like this into a repo can increase the barrier to keeping the documentation updated and also requires source-code control access to view, which not everyone has or should have to view documentation.
In my opinion, a combination of wiki documentation plus documentation within the repository are very good. In addition to that, I often use Google's office suite or Microsoft 365 for working documents, that is documents that need to just be written, get collaborative feedback, shared between external and internal people, etc. Then, once they start to solidify and start to get more atomic updates, it makes sense to move them to the wiki or a Markdown document in a repository.
People's problems with documentation are they don't want to deal with it. It's usually not about the systems used to document things.
The main point is you need ownership and responsibility. Wikis by design don't have those things, and it shows in how people actually use them. Wiki dumpsters are popular exactly because they let people abdicate responsibility, which means docs are no one's responsibility, because no one likes writing docs.
Then each team has their own wiki page with a list of "things we care about", each of which links to a separate page that was written using a template of headings, to get minimal (and QUICK TO CREATE) documentation. The template includes about a dozen or less things like: where is the source code, who are the key stakeholders, how do you build it, how & where is it deployed, how are backups done & who is responsible for them, what are the key high-level inputs and outputs, and what else is essential that you want to know, if anything. It is OK to put "N/A" as an answer (if that is true), but all sections are to be completed before it is released.
Those things are separate from the code which is why they are not documented inside the code. They can change even when the code does not, and might sometimes be maintained by non-coders. Code doc comments are more about saying why something was done, in the code, the way it was done.
Then have new people start with the wiki. It should include a section on what to tell new people. This is a potential way to learn, and the new person can have their first task be to update portions of it as they work on new things and work with existing team members. Every attempt to change the culture should be included in the wiki (for example: "we have a rule: no new technical debt. How will we preserve that rule going forward and not just forget like we did in the past? It goes in the wiki and we review it periodically and evaluate how we are doing."). Existing team members should subscribe to change emails so they can verify non-trivial changes!
If there is a QA function, they periodically evaluate (maybe just ask the team) how well the team does at maintaining the wiki pages and following the code review checklist, and reports that to management.
If you don't have people who can or are willing to do that, might be good to ask why, and we all start by looking at ourselves.
When there's a very limited set of curators, a specific topic, and a self-incentive to keep things "up-to-date" wiki's can be a great choice... mostly as like a knowledge base or internal glossary/dictionary.
For true "documentation" (if you don't take the wiki as a whole), and in the corporate world, I agree with the issues against using wiki's.
If you destroy wikis without an alternative, they'll be replaced with one of the worse options.
But Wikis are useful for things that are shared, or that are not tied to a particular product, or don't exist in the product yet. eg - "What's the temporary workaround for this bug?" - "How do I get started as a new employee?" - "What information do we need on customer requests?" - "What's the team process for handling escalations?" - "Here's the preliminary design for this new feature"
You still need someone to update those docs, but it's nice if, eg, the manager (or product/project manager) who isn't in Git all day can do it easily instead of asking a dev to do it.
Wikis do work for very large user bases, say documenting Stardew Valley mechanics. I think for very large teams, say 50, they start to make sense, especially if you're spending more time in meetings updating everyone than doing work.
Currently, we have a similar dumpsterfire running. Project / guideline / bla documentation hanging around in Confluence, technical documentation snippets in git repositories "near" the code they belong, some folks scourging themselves with Sharepoint and there's no solution in sight.
Me and some colleagues have developed quite some tendencies against natural language documentation because it basically becomes stale as soon as you publish it into your org.
I hate it for a very simple reason: the code (in BitBucket) and the documentation are disconnected.
I want my code and documentation to be coherent with each other. For small open-source projects (e.g. https://github.com/LaurentRDC/javelin), I love using doctests which ensure some level of coherence between documentation and code.
I span up a search engine that covered as many of those systems as possible (just SQLite FTS with Datasette, cron tasks that indexed various things and a simple custom search UI) and it helped a lot, because people at least had a fighting chance of finding stuff.
I believe there are off-the-shelf solutions for this kind of thing now, though I don't have experience with any of them myself.
I've since recreated aspects of the search system I built there as https://github.com/dogsheep/beta - you can see a working example of that system on the Datasette site here: https://datasette.io/-/beta?q=geojson
People like to say “Slack isn’t documentation” but in reality it’s a better documentation than some outdated Wiki nobody is touching.
My experience has been that most info is lost in DMs and video calls. When I helped coworkers, I had to be the one posting the info on public channels if I didn't want to be solving the same problem next week, next month, and half a year later.
We have decided that the best place for the "single source of truth" for that is right next to the appropriate code in git, with the various build/deployment scripts ensuring that copies (explicitly unmaintained, unmaintainable, read-only) of that get packaged with the actual systems, with the packaged libraries, linked in their web backends, etc. We don't care much about the format of the document, whatever fits the particular needs best - e.g. sometimes it's markdown, sometimes it's Excel.
The key factor here is to ensure that (a) there's a single source of truth; (b) you can have the same atomic commit/pullrequest/whatever altering both the system and the documentation at the same time; (c) every artifact has the appropriate version of the documentation, instead of going to some internal site or document which might have a different, newer version, you know what is supposed to be true for this release which actually is on this particular server.
I use (and work on) this: https://www.usenix.org/conference/srecon16europe/program/pre...
Basically docs live next to code or in a team-owned folder if there is no code. Code review happens whenever you change docs.
One process that ends up being really valuable for documentation purposes is our "Architecture Review Documents". This is a standard document that team leads fill out before starting work on a new Saga/Epic/Feature/whatever. It includes the scope and business value of a new feature or large block of work, high level technical architecture of implementation, the impact on existing database schemas and service APIs, etc. This document is presented in a meeting with technical leadership in our organization who deep dive on the topic and explore potential pitfalls in the plan.
The document and recording of that meeting live on forever, and this information is very useful when getting acquainted with a certain part of our product/codebase. You are able to read and hear clearly the intention of a certain service or module, and you can identify several relevant points of contact to ask questions to.
[0] https://backstage.io/
[1] https://arc42.org/overview [2] https://faq.arc42.org/questions/G-1/
* Wikis for general information, environment setups that are not project specific, etc.
* Repositories to host code and system specific information, usually in Markdown documents.
* Google Docs or Microsoft 365 for working documents that need to be collaborated on, commented on, and shared without the rigmarole of pull requests and the more static nature of wikis.
* Slack is for ephemeral information. If it contains documentation, specification, FAQ, debug steps, process explanations, etc., those should be captured and moved to the appropriate documentation location.
The one thing I really struggle with are diagrams. Cloud-based diagram tools like Visio and Lucidchart are great, but they are tough to save in a good location outside of the cloud environment. It requires exported the file and/or a PDF export. Then, these fit rather poorly into source-code control. There is the concept of "diagrams as code", but all of those systems are generally terrible at layout. There really is no good solution, as there are major trade-offs to both.
I've started using a similar approach, minus the png/jpg, for my personal markdown based wiki.git, saving the xml as a file that I can reimport in the future. I usually do this for prototyping or grokking some new system.
edit: just remembed, github also supports mermaid diagrams, https://docs.github.com/en/get-started/writing-on-github/wor...
I'm generally not a fan of exporting and importing diagrams constantly. One thing that is nice is that Confluence can support plugins for diagrams, which is okay-ish.
Other parts of the company use Confluence, but the docs with the code are what I pour my heart and soul into.
Slack is always a good resource, but I'd hardly call it "documentation".
* README, HOWTO, INFO, PROJECT, DESIGN, NOTES, FAQ
When I pull down a `git` repo, I read the `README.md` (of course). I make my own `NOTES.md` (eg: `.gitignore`'d) of what commands, environment variables, useful blog posts, search results, whatever. Rarely do I share or encourage sharing of `NOTES.md` wholesale, but it's helpful to be able to pull out a few snippets or re-orient myself when coming back to that software/project.
Then, other documents get prefixed with "HOWTO-Do-Some-Specific-Thing.md", or "INFO-Some-Particular-Component.md".
"PROJECT-...", and "DESIGN-..." are "dangerous" ones in that they can quickly fall out of date, but they can be very useful while they're being actively managed. I guess personally I've started making sure to include dates or "eras" in the title, eg: "PROJECT-[2024-Feb]-Add-Foo-Support.md" or "DESIGN-[2024-02-14]-...". Stuff that's outlived its usefulness can probably be moved to an `ARCHIVE/...` in case you need it later, but keep it out of the way from confusing newcomers 1-3 years from now.
"FAQ-..." almost never comes into play (hopefully) b/c it should mostly get absorbed into "HOWTO-..." or product improvements, and few products seem to rise to the level of needing FREQUENTLY asked questions. Ideally FAQ's would "go away" with work on the product or other documentation, but I've had some success with it as like sales-oriented (and ideally: sales-managed) FAQ / Canned Customer Response learnings.
Putting it all together you get something like:
Generally, they wouldn't all be "git-adjacent", but `README.md` should link to the other sources, `HOWTO-...` and `INFO-...` is generally good for your wiki/confluence/"published" documentation. PROJECT, DESIGN, and FAQ are all best as "loose" shared docs. Multiplayer by default with low barrier to edit/contribute. Sometimes DESIGN could be INFO-Design-..., or DESIGN might even be a DIAGRAM. You'll know it when you see it.Prefixing the documentation with the TYPE has been super-critical in adoption. It clarifies that it's not "DOCUMENTATION-About-Some-Thing.md", but instead "HOWTO...(you're gonna do something, goal-oriented)", or "INFO...(you're gonna learn something, no specific outcome)".
If you START introducing new prefixes, then you'll hopefully see them propagate (as appropriate), but ideally whatever vocabulary your business/team ends up using is small (~5-10 documentation types) would cover a good 80-90% of your use cases, and they should be brain-dead simple enough that it's clear their categorization is useful.
Framework: Choose a framework, like Arc42 for general layout as a good starting point. Remember you have company, quality, project, program, product, process, user, internal how-to's, etc. documentation types not just... user-guides and systems-architecture..so this will be dependent on your org/product. Go for MVP and 80-20.
Plan: Write a plan as part of the documentation that details all of these facets and rules so all contributors understand it.
Formats: drawio.svg for complex diagrams, mermaid for simple diagrams or if important to change manage like code, asciidoc for complex documents, markdown for most/simpler docs. Tables in csv or asciidoc. Images in svg, or png. Everything aforementioned renders on GitLab.
Other rules: Automate everything possible to reduce [manual] documentation. Use text/code vs proprietary formats.
You can get more and more complex with the tech writers, dev, ops, systems, all under one roof and coordinating documentation and pipeline scripting.
Meanwhile over in google docs it's a trash fire. There's no organization, just documents. At least sharing is possible, and the collaboration is clutch, but documents are copied, those copied edited, then not shared with the originals. It just goes on and on.
Then we have an intranet based documentation system called Papyrs. At least it's a wiki, but nobody maintains it, and search is best described as enabling users to rule out what they're looking for rather than find what they are.
Whatever you do, don't do what we did :)
EDIT: mentioned collaborative nature of google docs
[1]: https://docs.github.com/en/get-started/writing-on-github/wor...
Don't make me laugh.