Worth doing badly
On dead repos, hardcoded navs, and the version of a thing that actually exists.
There’s a G.K. Chesterton line that goes, “If a thing is worth doing, it is worth doing badly,” and the first few times I ran into it I assumed somebody had mistyped it. Surely he meant well, not badly! But it’s been rattling around in my head for a few years now and I’ve come around to thinking it might be the single most useful thing I know about getting anything finished.
The version most people know is “don’t let perfect be the enemy of good,” which is alright but I think it’s the weaker framing. “Don’t let perfect be the enemy of good” sounds like settling: you wanted the nice thing, but you have to accept the less-nice thing, womp womp. Chesterton’s phrasing is more aggressive than that. The poorly done version isn’t a compromise on the good one. It’s usually the only one on offer because the realistic alternative isn’t always a better version. Sometimes it’s nothing.
The graveyard folder
I have a folder called projects and it is mostly a cemetery. The thing I noticed going back through it is that almost none of them died because the idea was bad or because I got bored of the actual problem. They died at setup: choosing the stack, building out a design system before a single page existed to put it on, writing types for an API I hadn’t written yet. There are repos in there whose entire git log is three commits and all three of them are just tooling. You hate to open a project that had seemed promising and then realize the only thing you ever built was the scaffolding.
Meanwhile the stuff of mine that actually exists in the world got assembled like three raccoons in a trench coat did it. The first pass at my personal site was one HTML file with inline styles and a nav I’d hardcoded in three places. The one little tool I’ve written that I genuinely use in day-to-day life started as a single PHP file that shelled out to curl and printed a table. I’m not going to pretend that was good, but it got the job done and I still find good use for it, and no amount of doing it properly first would have bought me that.
And I don’t think the reason this works is discipline, or hustle, or any of that. I think it’s just information. A bad thing that exists tells you stuff: which part people actually reach for, which bit you got wrong, whether the premise was off in the first place. The immaculate version still sitting in your head tells you nothing. So every hour you spend perfecting something before it meets reality is an hour spent optimizing against a guess. Many of the abstractions I’ve lovingly built upfront turned out to be abstracting along the wrong axis entirely. How many of them did I actually need? Fewer than I built, honestly.
Every hour you spend perfecting something before it meets reality is an hour spent optimizing against a guess.
I know the counterargument here and it’s a good one: tech debt is real, cutting corners early leads to bigger problems down the line, and that hardcoded nav is going to come find me eventually. Fair, but I’d just say two things: (1) debt on code that shipped is a real debt with real interest, sure, but a project that never ships isn’t debt-free, it’s the entire principal written off; and (2) base rates. I’ve lost maybe one project to accumulated jank and I’ve lost a dozen to never properly starting. Those two failure modes are not remotely the same size, at least not for me, and I think it’s worth being honest with yourself about which one is actually coming for you.
Do it poorly but don’t be an idiot
The line I keep landing on is that badly is about polish and wrong is about correctness. A janky layout, an ugly file structure, three copies of the same helper: that’s bad, and bad is recoverable, and it’s recoverable later, by a version of you who knows more than you do right now. A form that silently drops submissions isn’t bad, it’s wrong, and shipping it doesn’t teach you anything except that you can’t trust your own site.
Outside the code editor
Anyway, none of this is entirely about web development. The place it’s helped me most is everywhere else.
A ten minute walk instead of the fitness program I’d have to plan first. Fifteen minutes of tidying instead of the Sunday deep clean that I keep putting off. Cooking something mediocre on a weeknight rather than ordering out for the umpteenth time because I don’t have the energy to cook something amazing. Texting a friend “hey, sorry, I’ve been a mess, how are you” two weeks late instead of waiting until I can figure out how to justify the silence.
Being visibly bad at something is its own hurdle and I don’t want to breeze past it because it’s uncomfortable. You get used to being competent at your job and then you pick up a hobby and you’re just openly terrible at it in front of people who aren’t. But again, the alternative on the table isn’t being good at it. It’s not doing it. All else equal, I would rather be bad at a thing than not have the thing, and it took me an embarrassingly long time to get there.
The version of this I’ve leaned on most, though, is one day at a time, which is the same idea wearing a different outfit. Nobody’s asking you to do it well, or to do it forever. Just today, and today is allowed to be ugly.
I do want to flag the obvious failure mode, because this is a very convenient thing to believe on a day you don’t feel like working, and I’ve used it that way plenty. The tell, I think, is whether the bad version is a step or a destination. If you never go back to it, you weren’t doing it badly on purpose, you were doing it once and quietly lying about the sequel. That’s a different problem and this principle isn’t a defense for it.
But if there’s something you’ve been circling for a month: the crappy version you could make in one afternoon this weekend is better than the beautiful one in your head, mostly because it’s the only one of the two that will ever exist.
Go do it badly!