Follow the Grain

Spend less time trying to fix things, and more time trying to understand them.

Last updated
Photo of Jay in Bazel

I’m a software engineer living and working in East London. I’m currently helping to build digital products & services at Red Badger. Although once strictly front-end, today I work across the whole stack, including dipping my toes into DevOps and writing  Rust & Go.

I think about Frank Chimero’s The Web’s Grain a lot. The bicycle-bear in particular:

“Listen bub,” I say, “it is very impressive that you can teach a bear to ride a bicycle, and it is fascinating and novel. But perhaps it’s cruel? Because that’s not what bears are supposed to do. And look, pal, that bear will never actually be good at riding a bicycle.”

Frank’s talking about the (then) obsession with building scroll-jacking, headache-inducing, CPU-igniting websites, but the idea is more broadly applicable than it seems.

In his recent talk The Layers of the Web, Jeremy Keith equated Brand’s ‘pace layers’ with the layers of infrastructure behind the web platform, with each layer being a different tool, technology or language evolving at a different pace. The best websites play to each layer’s strength, be that reliability or innovation, while the worst conflate them — say, for instance, by replacing several of them with JavaScript — sacrificing much of what makes the platform valuable. The most benefit is found by following the grain of each layer, not fighting it.

Most of us have a desire when faced with an unfamiliar technology or language — particularly one which at first glance seems less ‘sophisticated’ than our tool of choice — to fix it. CSS-in-JS is the poster-child of this mindset, which often stakes its claim on removing one of the language’s core strengths: the cascade. If you embrace the mental-model, writing with specificity in mind, you will rarely find yourself at war with it. SMACSS and BEM may seem unfashionable in 2021, but smart people were writing and managing CSS at scale long before styled-components came into being.

It’s not just today’s JavaScript obsession, either. At my second job we eagerly adopted Timber, a WordPress plugin promising to bring sanity in the form of the (admittedly excellent) Twig templating language. Real frameworks (such as Symphony and Larval) have real templating languages. Why not ‘fix’ WordPress? The resulting sites were fraught with bugs, integration issues and performed appallingly. It turns out that trying to substitute an integral part of a CMS is extremely problematic. The alternative? Work within the constraints, using helpers such as Humanmade’s template functions, and you can reap many of the benefits without incurring the same kinds of penalties. Lesson learned.

Yet just last year, whilst working on a React Native app, I spent a week trying to get the inheritance model to better mimic the behaviour I was accustomed to from CSS. Just last month the (seemingly) glacial pace of the Go generics proposal led me to spend far too long experimenting with code-generation and reflection-based solutions for re-implementing map/filter/reduce. It’s too easy, particularly when moving freely between languages and spaces, to bring baggage, not perspective. It takes careful discipline to stop, assess the tool, landscape and culture, then re-frame the problem you’re trying to solve. If languages are indeed like instruments, knowledge is transferable only so far as being able to read the music.

Post-ES6 it’s possible to write JavaScript which looks eerily similar to object-orientated code you might see while dusting off your copy of Clean Architecture, and thanks to Ramda it’s equally easy to write elegant, functional and point-free pipelines. Yet if you’ve ever tried to untangle an ungainly class hierarchy, or debug the endlessly recursive stack that Ramda’s currying produces, you might start longing for the flexibility of simple objects, closures and composition. Just listen to Crockford. Time has taught us that you can write Java in any language, but that you’ll almost always regret it.

That’s not to say that there isn’t value in crossing boundaries. In fact, that’s where innovation often happens — when people from one group bring concepts and ideas from a disparate place and let them percolate through, fostering new practises and ways of thinking. Yet the lasting fruits of these labours are not ports from one place to another, but evolutions that use experience to inform direction, not supplant what already exists.

We spend so much of our time fighting against the grain that we often miss the power of embracing what’s there. The next time you start down the rabbit hole, pause for a moment and think of the bicycle-bear.

← Archive