I code, found, write, and speak. Veteran CTO who built successful companies through empathic leadership and mastery of software delivery - from sustainable code to stakeholder trust. Now exploring the future of empathic and sustainable tech.
Dan McKinley's "Choose Boring Technology" gives you a budget of innovation tokens to spend on novel choices. I agree with all of it, and I want to refine one thing: a token is not denominated in how novel the technology looks from the outside. It is denominated in what your team already knows.
Bounded contexts deserve boundaries. But a boundary is a code concern, and putting a network between two contexts because you want them separate is a mistake. In-process interfaces are far easier to debug and to keep consistent than network ones, for a concrete reason: one compiler spans both sides and will not let them drift. Nothing spans the network.
A zoomable 3D scene of your architecture, with domains as planes, services as boxes, and data flows as glowing particles, demos beautifully, and WebGL makes it a weekend project. But 3D software visualisation never failed for technical reasons. It fails for perceptual ones, and those have not changed: occlusion, an arbitrary Z axis, label degradation, and depth being one of the weakest visual…
A while ago I promised to write more about feature flags. Here it is, as one flat rule: develop on main, and use feature flags. Long-lived feature branches are a problem you create for yourself, and most of the structural contortions teams adopt to cope with merge hell are there to solve a process problem with architecture.
I made this argument to my team again last week, while a neighbouring team was busy splitting their monorepo into around eighty repositories. People reach for a second repository when what they actually want is a boundary, and a repository is a ruinously expensive way to draw a line you can draw for free in the filesystem.
Every team eventually asks for "the architecture diagram", singular, the one picture which explains the system to everyone. That diagram cannot exist, because usefulness and audience-independence trade off by construction. The standards knew this in 1995. The answer is one model, many audience-specific views, and a clear separation between structural views and cross-cutting perspectives.
In the last post I argued against quality assurance as a separate activity. The same argument applies, almost word for word, to code reviews, and I am even less comfortable making it: at Qafoo we built a code review tool. On an internal product team the asynchronous pull-request review has become the default, and it is the wrong tool for almost everything we use it for.
I co-founded a consultancy that sold software quality for roughly a decade. The advice I am most certain about after those years sounds like a contradiction coming from me: do not do quality assurance as a separate activity. The moment a dedicated QA role appears, the developers quietly stop owning the quality of their own work, and that is the wrong direction.
Our data platform's frontends are catalogs, dashboards, and detail pages: request/response-shaped applications. We build them with server-side rendering, HTMX, and vanilla web components. The question is not "why not React", but which of our actual problems a client-side framework would solve. Walking through the inventory the answer was: none, at a price we would pay for a decade. As a bonus,…
BEM and CSS Modules solve scoping at the cost of making every element a one-off, and a pile of isolated components is not a design language. We style semantic HTML elements directly, constrain every color and distance to CSS variables, and use a small web-component base class instead of a framework. These old-fashioned rules matter more than ever now that LLMs generate frontend code faster than…
I left the start-up world not because I failed, but because I'd optimized for the wrong metric — I was building systems that scaled while being the system that wasn't. This is the post I wasn't sure I'd write, about why "Nothing Shared, Everything Gained" needed me to stop before it could be finished.
Every few years our industry discovers a new way to make software development complicated, but most web applications are not technically interesting — the interesting part is the domain. My book is deliberately boring: four layers, strict dependency direction, stateless services, and it worked the same way for five engineers and for seventy.
The entire architecture in the book fits into one sentence: Controller → Service → Gateway → Storage, with strict dependency direction and one job per layer. A distillation of practical experience, not a new methodology: four concepts that, put into perspective, prevent most structural problems from ever appearing.
Writing testable code is essential, but writing tests is not — at least not immediately, because comprehensive suites for code that might get cut next sprint are waste, not discipline. The actual non-negotiable is pushing side effects to the edges so that the code between them stays stateless, local, and changeable without fear.
A team that hadn't shipped anything in six months, controllers with NPath complexity causing integer overflows, 2000-line methods, and session arrays nobody understood — and twenty-five days later they were shipping again. The same pattern repeated across more than a hundred teams over seven years, and the common thread was always side effects.
Ten years ago I started writing a book about software architecture and then life happened: I co-founded a company, scaled it to seventy engineers, got acquired, and burned out. I expected the manuscript to be obsolete by now. Instead, the decade in between proved the ideas worked. The finished book is available at codethatships.com.
Vendors promise the industrialization of software development. What AI code generation delivers is fast fashion: cheap, disposable, and hiding a massive structural shift in power from the people who build software to the companies that control the means of generating it.
After fifteen years of founding companies and scaling commerce platforms, I'm now a software architect at FernUni Hagen, building a Learning Analytics data platform that helps students succeed, with a Modern Data Stack and consent-first design for highly sensitive data. I made the switch for meaning and work-life balance, and found both, plus an amazing team to work with.
I've conducted over 1,000 interviews and hired around 70 developers. My experience is clear: women with comparable qualifications consistently deliver better work, not because they're inherently better, but because the system forced them to be. Meanwhile, most companies' DEI efforts are pinkwashing, hiring still runs through bro networks…
I'm in a boring traditional marriage, but I built Hejme for complex families: divorced, blended, geographically scattered. Why? Because everyone I talked to had the same need: share with exactly the right people, not some platform's template. You decide who's family. The software should just make it easy.