My biggest piece of advice for anyone who’s making and building is to forget about perfection. Ignore perfection. Fuck perfection. Chasing it is the number one reason why people don’t finish their work.
On the one hand, this doesn’t make for beautiful code. It doesn’t make code that is a joy to look at or maintain. Generally, it’s code that has been built out of necessity, to do what is necessary.
But when you’re starting out, when you’re creating the first version of a product, you do have to be driven by necessity. You don’t have the luxury of perfectionism, your focus has to be on getting your product finished and shipping it.
You’re not existing or working in a vacuum, and you don’t have limitless resources to commit to turning your ideas into something perfect. Your only responsibility is to make something that works. Once you’ve made it work, you can make it better. But getting it out the door comes first.
You never improve on anything if it never moves past the theoretical stage. Until your code is out in the real world in the form of a working product, you have no idea what does and doesn’t need to be fixed. Until people are breaking it, you don’t know where the product is fragile.
So what about technical debt? Sure, it’s a real thing. But technical debt only arises when you leave imperfect code to fester, when you don’t have a regular schedule of updating and improving and iterating on what you’ve got.
I’d point you to my favorite idea around making anything. It’s the Beck directive, from Kent Beck.
- Make it work.
- Make it right.
- Make it fast.
…in that order.
That allows for constantly improving on what is actually functionally working. It’s a pretty simple explanation, in fact, of what an MVP is supposed to fucking do.
A mate of mine is a developer here in Sydney, and he always gives the same advice to his team. You don’t have to build it beautifully, you just have to build it.
His focus is on getting the work finished, getting the product shipped — there’s always room to turn it into a piece of art work later.
When I started talking to him about this post, he sent me a quote that sums up what I’m all about, and sums up my approach to making anything:
If your quick-running, hand-optimized system does not do what it is suppose to do, it is not worth investing time and resources in making it any faster. After making sure that the feature works correctly, you can focus on the performance of the feature. Once again, the tests act as a sidekick in that they will continuously provide you feedback whether changes broke the system. — Brian DiCroce
There’s never any point in polishing a turd. And you’ll never know if your work has any value until it’s finished, it’s out there, and it’s getting the job done. So that’s got to be the focus.
You have no idea how many people tell me they’ve been working on something, whether it’s an app or even just a blog post, and they haven’t finished or shipped it because they don’t know if it’s perfect.
They ask me how I know something has reached perfection, and I always respond the same way. I don’t. All I do is make it work. Because I can make it better as I go on, but I need to have a base level to start with.
You’re never going to have any impact on anyone or anything if you don’t fucking finish something. When it comes to competition, you don’t have to be out there building the most perfect product in the world — you just have to be the one who’s shipping a product that works.
There’s a lot of brilliant work out there that will never be as good as a hacked together hunk of code that’s barely sticking together. It will never be as good because it will never be finished.
If you’re a fan of Benjamin Franklin, you’ll recognize the title of this comes from one of his maxims: Necessity never made a good bargain. He was right, but when you’re working with necessity, you don’t always have the luxury of choice.
And when that necessity is just making something that works, your bargains may not be beautiful, and your code may not be beautiful, but you’ve just got to make it work.