I’m a big believer in monorepos so of course for this project I have decided to use a monorepo. I’m keeping everything (code, documentation, infracode, this website!, etc.) in a single repository on GitHub.

For the application code itself (both the golang-based backend and the svelte-based frontend) my approach has been for each component to behave as if it was the only thing in the repository. Meaning, that the go.mod, go.sum, and main.go files live in the repository root and the subpackages live in directories also in the root (e.g., cmd for the cobra files). Similarly, for the frontend the package.json, package-lock.json and other frontend configuration files such as svelte.config.js or vite.config.js also live in the root. It’s made a little bit easier by the fact that normal sveltekit expects the main application code to be in a directory named src and so the frontend code is still separated a little bit from everything else. Integration tests with playwright live in the standard tests folder (compared to unit tests for both the frontend and backend that live next to the original source files).

Other special cases are the code for this website where the hugo configuration has been initialized into a directory called www, documentation (meaning special setup steps, references, procedures for provisioning or maintenance, etc.) is in a directory named docs, and the infrastructure-as-code (terraform and ansible) in a directory called infra.

This lets me keep everything in a single project without needing too many moving pieces and for my own mental model is much simpler. The only downside has been for automation with GitHub Actions the push targets need to be well-defined in order to avoid running useless pipelines (e.g., if I change this website’s code I only need to rebuild and deploy it - I don’t want to re-run terraform or run linting, tests, etc. on the application code, etc.).