Automation vs Documentation
How to replace fragile process docs with tools that enforce standards automatically.
If you have read my blog posts before, you know that in my projects, I enjoy having documentation that enables quick onboarding, makes knowledge available 24/7, and makes things organized. While I put some emphasis on documentation, I agree that documentation can be overdone and sometimes become a threat instead of an ally. That’s why I identified some places that require being properly documented to work well, but can be replaced by more user-friendly things than following a checklist or reading long documents.
That’s mainly the case with process documentation. Describing multi-step flows can be a great way to make people understand how it works, but it comes with the risk of being outdated quickly.
The main purpose of documentation is to explain “why”. Documented conventions and processes help build a common understanding, but it does not help ensure that they are being followed. In this case, documentation should be supported with automation.
Automating with Scripts, Generators, and CLI
Usually, running the app and setting up the local environment is a multi-step process that might or might not be included in a project's Readme. This not only wastes the developers' time but might also be tricky as the steps become outdated in the future. The goal should be to automate this process as much as possible so you can run the project with just one command.
To do that, you can create your own simple CLI tool. CLIs can be great for running your project, generating new files, or configuring setups. The tool that I can recommend for creating CLIs (if you are familiar with JavaScript and React) is Ink.
When working on a codebase with some standards regarding where to put files, how to name them, and even how to connect them to other parts of the codebase, it won’t be effective to create documentation and let the developers do the work. They will look for similar code, copy-paste it, and then fill it with their own code. You can create generation scripts that will generate the files for them. Some projects do that well - Nest.JS generates files from the CLI, adding all the boilerplate automatically.
Creating scripts is great for installing required packages, generating project configuration files, and adding custom behaviors to other tools.
Linter, Custom Rules, and Warnings
Educating the team and introducing new practices that everyone should follow is a very difficult process. It should be communicated through different channels - documentation, Slack messages, or emails. In this case, documentation shouldn’t be the main way to ensure everyone remembers to use those rules; rather, it should support communication. What you want to achieve is actually to enforce this rule and track if someone breaks it.
You can use automated tools, such as a linter, to add a new, custom rule. If someone forgets about this rule, it will display an error or warning. If the rule is broken, it can also prevent committing or pushing the code to the repository. You can achieve this with hooks such as Husky.
When refactoring the codebase, enforcing a new way of doing things is usually problematic. In my case, it was moving some code to a different package to make the main one leaner. Although the change was communicated to the whole team, some people created new code using the old package. It happened during a migration process to the new package, making removing this from the old package impossible. Documentation as a communication tool was not enough, and the solution for this issue was to deprecate old methods. This way, the IDE highlighted it as deprecated with a comment that you should use import from a different library instead.
Other tools also validate how things are done in the project. One is a commit lint that allows you to set rules for the commit messages. It’s usually messy in new projects - some people are not doing meaningful commit messages or making them too long. You can enforce rules such as “conventional commits”, the length of the commit message, and you can require a JIRA ticket ID. It’s way more valuable than creating detailed documentation describing how the commit should look, and assuming everyone will follow the instructions. Documentation should be a supporting communication channel that describes a good commit example.
Shared Configs and Plugins
IDE has many customization options, and experienced developers usually have their own preferences. For people switching technologies or beginners, achieving productivity with their developer toolset is challenging. You can share proposed IDE settings to improve their onboarding and allow them to be more productive. It might be done as documentation explaining the tooling and conventions, but sending them your configs is the best way.
The best way to achieve consistent coding styles is to use a “.editorconfig” file. It standardizes basic code styles such as indentations, character encoding, and trailing whitespace handling.
What I found the most useful was sharing the IDE configs, such as workspace-specific settings or the list of plugins that I use. Plugins are especially important for improving team productivity. A good plugin can improve linting, debugging, or reading the code. IDEs have different ways of sharing the configs, but in VSCode, you can share your settings.json and extensions.json files.
Summary
While creating documentation or properly automating boring tasks takes time, it brings a lot of value. The biggest value is in enforcing standards or enabling developers to follow good practices just by running simple automations. Properly communicating such changes and encouraging developers to follow documented practices can be a really difficult task that automation can easily solve.







