The Stack That Accumulated
Every rewrite taught me something the next stack inherited

The Stack That Accumulated
I'm a software engineer, and I've learned a lot along the way. That sentence does more work than it looks like it does. Every stack I've shipped on has taught me something the next one inherited, and every stack I thought was the last one turned out not to be. The thing I'm building now — foliokit, the library suite this blog runs on — is the first one I've put together with both eyes open about that pattern. This post is about how it got that way.
I opened the foliokit monorepo this morning and stared at the Nx dependency graph for longer than I'd care to admit. Models feeding API, API feeding the editor, the editor feeding the blog you're reading this on. It looks intentional. It looks like someone sat down and designed it.
They didn't. I didn't. This stack didn't arrive — it accumulated. Every layer in foliokit is a lesson I learned the hard way from a stack I no longer use, and the only thing I got genuinely right was eventually noticing the pattern.
Before any of this was a stack, it was just languages. Turbo Pascal taught me that programs have structure and that structure is something you design, not something that happens. C++ taught me the compiler was both my closest collaborator and my most exacting critic — a relationship I've been in ever since. Visual Basic taught me that productivity and discipline are not the same thing, and that the language which lets you ship fastest is not always the one you want maintaining your code at 2 a.m. None of these were rewrites. They were the foundation the rewrites would later sit on, and they're the reason the next lesson landed as hard as it did.
From 2012 to 2016 I built things in ASP.NET MVC. Razor views, controllers, Entity Framework, the whole catechism. I shipped real software with it and I liked most of it, which is the part younger developers tend to skip over when they hear "ASP.NET" and pull a face. What MVC taught me — and what I didn't realize I was learning at the time — was that typed contracts between layers are not a nicety. They're load-bearing. When the model changes, you want the compiler yelling at you in seventeen places, not the QA team finding out in production. Foliokit inherited that lesson directly: @foliokit/models exists as its own library, separate from everything that consumes it, because the contract is the thing that has to survive every rewrite.
Then in 2016 I discovered AngularJS, decided server-rendered pages were over, and spent about a year writing two-way bindings that updated each other in loops I couldn't trace. AngularJS was the framework that taught me to distrust magic. $scope felt like a gift until the day it didn't, and by then you had a directive graph that nobody — including the person who wrote it, who was me — could reason about. I came out of that era with one strong opinion that's never left me: explicit data flow beats convenient data flow, every single time. Foliokit inherited this as a posture more than a pattern. When I'm reaching for something clever, I now assume the clever thing is the thing I'll regret in eighteen months, and I reach for the boring thing instead.
By 2017 the Angular 2+ rewrite landed and I made the jump along with everyone else who'd bet on AngularJS and was now quietly furious about it. The rewrite was painful in ways the changelog didn't capture, but it taught me the lesson that ended up mattering most: rewrites are survivable. The world doesn't end. The framework you swore you'd never leave will leave you, and you'll be fine, and the next one will teach you something the last one couldn't. Angular 2+ also gave me dependency injection that actually worked, RxJS when I needed streams and wasn't just performing reactivity, and a component model I could grow into. Foliokit inherited the whole runtime — but on my terms this time, not the framework's.
The honest version of how foliokit's stack got chosen is that I stopped fighting. Three times in a row I'd picked a stack thinking it was the last one. Three times in a row I was wrong. By the time I started foliokit, I'd finally internalized the thing I should have known from the start: there is no final stack. There's only the stack you're using now, and the question of whether the parts that matter will survive when you replace it. Foliokit is the first thing I've built with the explicit assumption that I will, eventually, rewrite parts of it — and that the architecture has to make that survivable rather than catastrophic.
So here's what's actually under the hood, and why.
Angular is the renderer, but it's Angular with the lessons applied. Standalone components from day one, because NgModules were the framework magic I'd learned not to trust. Signals where they fit the shape of the problem, RxJS only where streams genuinely model the domain — not as the default reactivity primitive, which was the AngularJS-era mistake in new clothing. The framework choice is the least interesting part of foliokit, which is exactly how I want it.
Firestore is the backend, and that's a more deliberate choice than it looks. The content model — Posts belonging to Series, with bidirectional traversal — maps cleanly to documents, and I wanted out of the schema-migration treadmill that haunted the MVC years. Document stores aren't a free lunch; I trade joins for denormalization and have to think harder about consistency. But I trade them knowingly now, which is the only kind of trade worth making.
Nx exists because foliokit is a library suite, not an application. @foliokit/models, @foliokit/api, and the editor pieces are designed to feed multiple consuming apps. The blog at dougwilliamson.online is the first and currently the only consumer, which is on purpose — I'm dogfooding the library before I scale it to the gaming platform that's coming next. If foliokit can't survive being its own first customer, it can't survive being anyone else's.
I won't claim the next rewrite is coming, because I genuinely don't think it is — not in the way the last three did, where the framework or the framework's owner decided for me. Foliokit is the first stack I've built where the parts that matter aren't tied to anyone else's roadmap. The models layer doesn't care what renders it. The API layer doesn't care what stores it. If something does eventually have to be replaced, it'll be a part, not the whole.
The goal was never a stack that never changes. It was a stack where the parts that matter outlive the parts that don't. Foliokit is the first time I've built one — and the first time I've stopped bracing for the next rewrite.