Oversteering your project

I’ve been working as a consultant for over fifteen years. I’ve seen tectonic shifts in browsers, the rise of MVC frameworks and the subsequent cult of Functional Programming, and I’ve seen so, so many tech stacks come and go. I’ve watched C-Beams glitter in the dark near the Tannhäuser gate. This also means that I’ve greenfielded more projects than I care to count. And an interesting pattern has emerged around how people handle choices and past mistakes. Let me tell you about it, starting with two stories.

The story of finding seemingly great tools

Back in 2011, everyone was really into Backbone.js. I was at my previous company doing frontend work for various household-name companies, we dipped our toes in client side rendering for some smaller projects, and you know what? It felt great. You could turn your server into a JSON pump, use Backbone.js as a sort of ORM and then render everything with JavaScript. Pages seemed to load immediately! We had Optimistic UI doing seemingly instant updates, and deploys were suddenly super easy: just uglify your JS and overwrite the bundle that’s already there. This quickly became our preferred way of working: we’d extol its virtues to clients, show them our cool transitions and instant responses, and everyone was happy.

Then a high-profile project came along. It had some interesting quirks but didn’t seem all that complex. We went full steam ahead with Backbone, and had an external partner providing the JSON for us. Prototyping went really quickly, and then we went on to expand it out and build the real thing.

And then… we crashed and burned.

Turns out we had underestimated the complexity of our project and with Backbone only providing the bare minimum, suddenly we found ourselves building all manner of abstractions and concepts to deal with it. And it wasn’t holding together. It was a bug-ridden mess and project morale went through the floor. We got it delivered, but it took a heavy toll on us.

The story of finding seemingly great processes

Facebook used to be proud of “moving fast and breaking things” but these days you’ll usually find it said in a derogatory manner. I’ve been through the same thing, writ small: I’ve built UI and design systems at a breakneck pace and I have to tell you, it feels amazing. There’s always an axiom or truism to wield. “Duplication is better than the wrong abstraction.” “Premature optimization is the root of all evil.”

Well, then you onboard more developers. They don’t quite understand what you’re doing and there’s not much documentation. And suddenly your CSS resembles an enormous gordian knot of human hair (sorry for the image) and everyone has copied and pasted and made tiny changes to your components and there’s never enough time to exhale, take stock, and refactor. Everyone’s crossing themselves before pushing a commit and velocity drops precipitously. I am not alone in having experienced this.

Then what?

The news will spread quickly: avoid JavaScript rendering. Accept no less than 100% code coverage. Start a committee to review incoming UI component changes. You got burned, you’re trying to avoid the fire, but now you’re headed straight for the thorn bushes on the other side because these are examples of oversteering. Every time we make a fresh start, we think “man, I won’t make THAT mistake again” and happily bumble into the ditch on the opposite end of whichever road we were trying to stay in the middle of.

But how do we avoid oversteering?

First of all, know that you’re doing it. You’ll always spend more time thinking about the warts and imperfections of your project since they’re the ones tripping you up and annoying you. The things that work smoothly you take for granted. This practically guarantees you’ll be jealously looking over the fence at other processes or technologies. Wanting to improve is a good impulse and you should definitely be trying to reach out of your comfort zone with every project, but try not to leap outside of it completely. You don’t know the tradeoffs yet and people are relying on you to make informed decisions, not buy lottery tickets for your code.

You’re also going to need a healthy dose of scepticism toward everything you read about tech stacks and processes. I mean, go ahead and read the puff pieces and test things out, but trusted and boring tech is almost always the better choice — you need to walk a mile in that hot new library’s moccasins before you can pass judgment on it, even if it’s sold as “web scale”. Learn to trust your own instincts, and not the siren song of the Internet. If the shine is real, it’ll still be there in a year or two. It’s really easy to think that everyone else is out there knowing exactly what they’re doing, when in reality they’re probably muddling along just like you, but trying hard to make it look like they’re CRUSHING IT.

It also helps to be reflective about these things. Hold retrospectives and think about how to refactor, isolate, or control the difficult parts of your code, rather than throwing everything out and starting over with a completely different ethos. And try to keep the metaphor of steering in mind: if you want to go fast, keep your hands on the wheel, your eyes on the road, and steer smoothly. You want to get to where you’re going, not end up on the side of the road.