“Writing documentation is fun!” - This sentence is probably not said very often by developers around the world. In this post, I want to share how we write the user documentation for Lighthouse, and why I believe that may resonate with developers.
You can see the end result of our documentation at https://docs.lighthouse.letpeople.work:
Lighthouse is the flagship product of Let People Work. It allows you to forecast completion dates with confidence and supports a wide range of scenarios, including projects with multiple teams and handling features that are not broken down yet.
It’s free to use, is open-source, and doesn’t need any cloud connection.
Join our Slack Community to learn from other users and become part of the development.
Documentation Experience
Up to now, I’ve experienced two kinds of documentation:
User-facing documentation, most often written in a dedicated tool like Word or dedicated Content Management Tools
Documentation aimed at developers, most often written in markup languages (like Markdown), for example as part of a README or Wiki
In my experience, developers often dread the former, as it’s connected with something that you just have to do, not something you want to do. You have to use those annoying tools (that are very different from what you normally use day-to-day), and due to that, we try to delay this as much as possible. So when we finally can’t shift it anymore, we don’t remember the details which makes it even more of a slog and just reinforces the belief that this is annoying work.
“Developer Documentation” usually flows better. It may not be everyone’s favorite task, but it’s often less of a pain to do this.
My assumption is this is because you can stay within the tools you are used to, and the documentation work is often done much closer in time since the change that is being documented happened.
The whole experience feels different when I modify a Markdown file, commit the changes, push them to a repository, and the change is instantly there.
With this in mind, we tackled the User Documentation for Lighthouse as well. But before we get there, let’s quickly talk about one of my favorite topics: Automation.
Automation Automation Automation
I love automation. It’s one of the coolest feelings if you can automate something that was a cumbersome manual task before (especially if it had to be done repeatedly). It’s right up there with getting your tests to pass.
When I recently was writing my CV, I was putting the following in the About Me section:
Automation of anything and everything is another passion of mine. Whether it’s a script that can collect some data automatically or a CI/CD pipeline for this CV, it’s something I genuinely enjoy doing.
This was supported by the fact that the whole CV itself is written in LaTeX, and a CI pipeline is creating a PDF out of this and publishing it. Instead of a time-stamp, the CV is versioned (well the version is based on the last change date, but still).
What I’m trying to tell you is that I’m serious about automation. Apart from me enjoying to do it, automation will lead to many improvements:
It democratizes knowledge and makes it available to anyone. We don’t depend on a single person remembering how to do a thing, even if that person is yourself (I certainly don’t remember that LaTeX command to compile my CV…)
You make a process repeatable
Ideally, you also make the process versionable (for example by storing all the things needed to run the automation under version control)
You remove waste, as you don’t need to spend time doing that thing manually and instead can spend it on other things (like automating more things!)
Note that just because something can be automated, doesn’t mean it’s worth it. There is always some cost to create the automation, which may be a lot higher than what you save.
As Lighthouse is something I’m spending my evenings and weekends on, and we concluded that “proper documentation” may be worth having, I combined it with doing something fun and automating as much as I possibly could. But before we get that, let’s first dive into why we concluded that the documentation was worth having.
Why Bother To Create A Documentation?
Initially, we had all the documentation on GitHub itself, as part of the README.me. This works but also expects that users are willing to navigate to your GitHub project and browse through the Readme. The experience is not ideal, and not everybody is a developer and wants to deal with GitHub (which looks scary with all those files and badges and pipelines, etc…). You also lack a decent search (for the documentation itself) as well as some elements to structure a document.
As more people got onboarded to the tool, we noticed that similar questions were popping up, and some would have been answered in our Readme already. Which is an indication that people do not read through that.
We took this as a feedback and decided to invest time into a documentation that:
Is well structured (or at least could be well structured)
Is easy to write and extend
Can be searched
We could host online
We could automate the heck out of (maybe this was just my requirement :-)
Read on to learn what we did in detail to achieve all of the above.
Documentation as Code
Based on my previous experience, I aimed at a solution that was done in Markdown (or similar). That would allow us to keep using the same editors as when we change code, and we could have the documentation in version control. In fact, we can keep it in the same repository as the application itself.
The documentation then is no different from the code. It’s as much part of the application as anything else.
As we were using GitHub to store our code (did we mention that Lighthouse is free and Open-Source?), it made sense to use a cool feature from GitHub for the documentation: GitHub Pages.
GitHub Pages allows you to host a website directly from your GitHub repository. Push some changes, trigger a CI Pipeline, and within a minute, the new version is published. And all of this is based on markdown files in your repo.
Two cool features from GitHub pages are:
You can set up custom domains, so instead of a default URL, it can be anything you want it to be (assuming you own the domain). This allowed us to host our documentation under https://docs.lighthouse.letpeople.work, even though it’s hosted on GitHub itself.
GitHub supports Jekyll, which allows you to use various themes to create static sites based on your markdown files.
Just The Docs
One of the available themes for Jekyll is Just The Docs. As the name suggests, this is a theme that helps you write nice documentation. It’s free to use, very simple yet powerful, and needless to say, the documentation of the theme is great.
Jekyll is based on Ruby and you can run it with any template easily on your local machine (for example before you set up your CI Pipelines on GitHub).
Once done, you can work with Markdown as you are (most likely) used to. In Lighthouse, we keep our documentation within the docs folder and create subfolders for each area that we display in the navigation.
While Jekyll respectively Just the Docs add some configuration options (for example the frontmatter on top of the file to describe the page details and navigation), you can mainly use the regular markdown syntax that you know (and love). Create links to other pages, use # for your headings, add tables where they make sense, and insert pictures to visualize what you’re describing. Which brings us to the topic of screenshots.
Screenshots!
It was not long after I started writing that I thought I should add a screenshot. Easy thing, just let me spin up the app and capture one. Store the file in my docs/assets folder, reference it, and it works.
Except, what if the app changes. I obviously should retake the screenshot. But do I remember that? And it would be nice if all the screenshots would follow a similar pattern (for example use the same team/project names). I could sense that either I’m automating this right away, or we will have not updated screenshots very quickly (automation = fun, taking screenshots = boring).
In Lighthouse, we run end-to-end tests using Playwright. This is a great tool for testing, but the fact that it’s spinning up the app automatically, putting it in a known state, and can be run from our pipelines, made it also interesting for taking screenshots.
If you write your testing framework in a decent way (which you really should), you can reuse all your page objects for the sake of taking screenshots. Then very quickly you get simple tests that you can use for recapturing screenshots. To take the screenshot you see above in the Feature Page, this code is used:

Without going too much into the details, the test uses a tag (@screenshot) and then spins up the application, puts it into a known state (updating Teams and Projects), navigates to the Overview Page, and takes the screenshot.
As we can run Lighthouse in docker, we can spin up a container to test against (to make sure we don’t have any leftovers of some other testing we did):

The argument --grep @screenshot will make sure we only run tests with the @screenshot tag.
And our takePageScreenshot method also checks if the image is different than the one we currently have, and will only save it if that’s the case (with some threshold). That way, we don’t spam our git history with minor changes (for example if just the date is updated).
Pretty cool stuff so far, but to complete it, we want to run all of this automatically.
Pipelines!
The final piece of the puzzle is the Continuous Integration and Deployment. Lighthouse has three CI Pipelines:
The main pipeline is building, testing, packaging, and deploying Lighthouse.
The docs CI Pipeline is triggered if anything within the docs subdirectory is changed. This will redeploy the Jekyll page and deploy it to GitHub pages.
The screenshot pipeline, which can be triggered manually (and then runs against the latest dev docker image), also is triggered if any new release is created (and then runs against this specific version).
The screenshot pipeline is running the Playwright tests that create the screenshots (if they changed). On top of that, it will create a Pull Request so a human can manually review the changes:
If the pipeline is rerun, the PR will be updated with newer screenshots (just in case something needs a fix). Once merged, the docs pipeline will kick in (as we changed something within the docs folder) and the latest screenshots will appear in our online documentation within the next 1-2 minutes.
If you don’t find this cool, I really can’t help you.
Conclusion
Not that you needed any evidence, but I think this post is proof that I really like to automate stuff. At the same time, I did notice how much easier it is to write user documentation in Markdown. It just feels more natural than using some other WYSIWYG editor. I hope I could inspire you to also think about how you write your documentation, I can highly recommend this approach!