I Am a Cross-Cutting Concern

I have 76 Go projects, 61 PCB designs, 51 PlatformIO firmware projects, hundreds of technical notes, my resumes, my tax documents, and a ray tracer. They all live in one git repo.

The repo is called slam. It stands for Scott Lawson's Awesome Monorepo, a name I'm not going to defend. I chose it because I knew I'd type it thousands of times and wanted something short. Today it's just slam.

Collage showing the breadth of the slam monorepo: KiCad PCB designs, a pile of fabricated circuit boards, the Battleaxe multiplayer game, a parts database CLI, and a pick-and-place machine with illuminated LED ring
One repo. PCB designs, multiplayer games, robot controllers, firmware, and more.

What unites all of these seemingly unrelated projects is the same thing: me. In software, a cross-cutting concern is something that touches every part of a system even though it isn't the main purpose of any one part. Logging, authentication, error handling. They cut across everything. In my monorepo, I'm the cross-cutting concern. I'm not the purpose of any individual project, but I'm the thing that touches all of them. That turned out to be enough to put them in one repo.

I Was Losing My Code

Before slam, my projects lived in dozens of small private git repos scattered across different computers and operating systems. Most of them were tiny. A PlatformIO project for testing a microcontroller. A one-off LED animation. A small tool I wrote for a weekend project. None of them individually felt important enough to maintain properly.

But I was losing them. Not dramatically. In the slow, quiet way that happens when you create things on different machines over the course of years and never give them a proper home. I'd remember writing some code for an ESP32 a year ago but couldn't find which computer it was on. I'd want to reuse a sensor configuration but couldn't remember which of my thirty repos had it. Notes and technical references were scattered everywhere.

The other problem was that most of these projects weren't "enough" to justify their own repo. They were early stage, small, and often one-off. But they weren't nothing either. For microcontrollers especially, I found myself constantly wanting to copy chunks of PlatformIO configuration from one project into another. I needed a home for things that were too small to stand alone but too useful to lose.

In 2022, I created slam and started pulling everything in.

One Place for Everything

The top-level structure is simple. Short names, clear boundaries. 48 Go modules coordinated by a single go.work file.

slam/
├── code/    # Software projects (Go, C++, Python)
├── pcb/     # KiCad PCB designs with firmware
├── hack/    # Experimental projects and prototypes
├── edge/    # Infrastructure config, Cloudflare tunnels, machine provisioning
├── note/    # Technical notes and reference material
├── post/    # Blog post drafts
├── rule/    # Conventions and patterns
├── bbb/     # Business administration
└── me/      # Personal documentation and resumes

I didn't design this structure upfront. It emerged over time as I moved projects in and noticed what belonged together. The important thing was getting started, not getting it right.

The Garage

The distinction between code/ and hack/ was one of the first decisions I made, and it turned out to be one of the most important.

Some projects have a clear structure from the beginning. A blog, a raytracer, a multiplayer game. You can sketch out an architecture and build it up. But a lot of what I do is exploratory. Testing a new microcontroller. Trying an LED animation idea. Reading a sensor for the first time. These projects don't have a well-defined future and they don't fit neatly into existing patterns.

hack/ is where they go. I think of it as a garage. Ideas live there while they figure out what they are. Some graduate to code/ or pcb/ when they take shape. Others stay as experiments forever. Both outcomes are fine. I got this idea partially from Go's /x/ packages and partially from Google's monorepo, which separates //experimental from production code.

But the garage turned out to be more than just an organizational tool. It's the place where things that seem unrelated can sit next to each other long enough for me to notice patterns. Hundreds of small PlatformIO projects for different microcontrollers, each one a snippet: how to control WS2812 LED strips, read a sensor, communicate over I2C, drive a servo. Before slam, these were scattered across computers and I was slowly losing them. Once they were all in hack/, I started spotting recurring boards and configurations. I created note/ to hold technical references about the hardware I worked with. The archive grew into something I could draw from for every new project.

None of this would have happened if the snippets had stayed in separate repos on separate machines. The cross-cutting concern needed a place to accumulate before it could be recognized.

Connections I Didn't Plan For

The monorepo started as a dump. A place to stop losing things. But over three years, connections emerged that I never planned for. This is the part I didn't expect and the part I find most interesting.

I wrote a fast UART driver for controlling serial instruments with low latency. I built it for a microscope project. A year later, I needed the same driver for a robot controller. Because both projects lived in the same Go workspace, I could import the package directly. No publishing, no mirroring, no spinning off a new repo. A microscope and a robot have nothing obvious in common. But they share me, and I needed low-latency serial communication for both. In separate repos, that connection might never have happened.

I started with one web server I cared about deploying: a multiplayer game. I put it on Heroku. Then I built a Vietnamese dictionary. Then a monitoring tool. Then a robot dashboard. Then a blog. Each one was its own Go project in slam. After the fifth or sixth server, I noticed the deployment pattern repeating and built a CLI tool that could operate on any project in the monorepo. The incremental cost of adding another service dropped to nearly zero. I now self-host over a dozen services through Cloudflare tunnels.

The slam CLI showing commands for deploying, running, monitoring, transferring files, and configuring machines and Cloudflare tunnels
The slam CLI. Deploy, run, monitor, transfer files, configure tunnels. One tool for everything in the monorepo.

That CLI tool only made sense because I had accumulated enough projects in one place to justify building it. The pattern was invisible when I had two servers. It became obvious at six. The monorepo made it visible because everything was in one place, and I was the thing connecting them all.

Having everything in one repo also turns out to be very convenient for working with AI coding tools. I can say "help me create a new robot driver, and look at the UART driver I wrote at code/photon/driver/uart for reference" or "structure this website like I did in code/bietviet." Without a monorepo, I'd need to make sure each reference project was checked out on whatever machine I'm using. With slam, I always have everything. One checkout, full context.

It's Contagious

I shared some screenshots of slam in a friends and family group chat. The directory structure, the CLI tool, how the projects fit together. Two people in the group were inspired enough to create their own personal monorepos.

One person created a repo called "claw" with a CLI tool that has a Trello-style task manager built right in. Another person created "LAIR" (Lab Automation Infrastructure Runner), focused on DevOps workflows like Docker, SSH, and Git automation. A third created "MapleForge" with commands tailored to their own projects. Each person picked a name that means something to them, organized things their own way, and built tools that solve their specific problems.

The LAIR CLI tool showing commands for configuration, Docker management, SSH, Git operations, and project scaffolding
LAIR: Lab Automation Infrastructure Runner. DevOps-focused, built around a completely different workflow than slam.
The MapleForge CLI tool showing ASCII art maple leaf logo and commands for package management
MapleForge. Different person, different domain, same idea.
The claw CLI tool showing a Trello-style task management command with personal task boards and lists
claw: Chris's Lifetime Accumulated Work. A personal Trello built right into the CLI. Your monorepo can be anything you need it to be.

Every one of these CLI tools was created with the help of Claude Code. All of them. The barrier to building a personalized command-line tool for your monorepo has dropped dramatically. What used to take weeks of scaffolding can be done in an afternoon. The hard part isn't the tooling. It's deciding to put everything in one place and trusting that it will grow into something useful.

The Freedom and the Risk

A personal monorepo is a fundamentally different thing than a company monorepo. At a company, you have communication costs, coordinated releases, shared ownership, and the need for systems like Bazel to build everything uniformly. None of that applies when it's just you.

When you are the only user, decisions have zero communication cost. Breaking changes can be made instantly. You don't need permission, review, or consensus. You are this amazing little dictator who can do whatever you want because it is your space. Don't set up Bazel. Don't design a perfect directory structure upfront. Do things that don't scale. Just get started and evolve it over time. Use short names. Keep large binary files and media collections somewhere else. Stick to what git is good at.

The biggest weakness is security. I keep sensitive information in slam. Resumes, tax documents, some API keys and secrets. The repo is private, I'm the only user, and I only access it on machines I control. But I won't pretend this is ideal. It's a huge airtight hatch: if someone gets inside, they get everything. I'm still looking for a better way to handle this, ideally something self-hosted. I'd love to hear suggestions.

The Cross-Cutting Concern

If you're late in your career and you've already built a workflow that works, keep doing what you're doing. You've solved your problems and a monorepo won't magically add value.

But if you're a recent graduate, or someone who hasn't worked out all the patterns yet, or you're intrinsically motivated and build things for fun across different domains, consider giving it a try. A raytracer and a circuit board don't obviously belong in the same repo. A robot controller and a Vietnamese dictionary don't share a language, a domain, or a purpose. But they share me. And having them in one place created connections, tools, and patterns that I never would have discovered otherwise.

The conventional wisdom is to organize projects by what they are. I organize by who made them. There's only one of me, so there's only one repo.

You are a cross-cutting concern too. Your repo is waiting.