Reflections on failing to ship
View of Deventer Seen from the North-West by Salomon van Ruysdael
Shipping is hard. Really hard. It’s been one of the primary challenges I’ve dealt with during my life building software.
What you ship to the world can often feel like a reflection of yourself; a portrait of your skills, your intelligence, your values. It can be a scary thing, especially when your critic can be the anonymous, unforgiving entity of the Internet… or even worse: yourself.
I’ve written a lot of code. I’ve spent months, even years, building projects that I felt would be valuable to the world, become viral on X, or just bring joy to a few people. Yet, they live only as private repositories in my GitHub. They stay locked away, aging as the dependencies become outdated, and I grow resentful of what my prior, less-experienced self considered to be well-written code.
In a world of agents, shipping has become trivially easy. Agents can productize an app without you needing to understand servers, databases, or even programming. And in a world of serverless compute, you need not worry about much more than your app’s business logic. Despite how easy it’s become, I still fail to ship. I still fail to make a repository public and post about it on Hacker News. Here’s some advice I’m giving to myself to ship more.
It’s OK if your code sucks
If it becomes useful, chances are it’s gonna be completely rewritten anyway. I’ve spent hours refactoring, rewriting, and rethinking large swaths of my code, just in case someone looks at it and decides I’m an idiot. Those people will think you’re an idiot regardless; they’ll find a reason to hate.
Bad code runs the world. And as much as it pains me to accept that, I don’t think I’ll get very far ignoring that truth.
You don’t have to be you
Part of my fear of shipping is that it’s tied to my identity. When a project has my name on it, subpar software and code feel like a personal failing. I flinch at the idea of people judging me, but that can’t mean that I should avoid putting myself out there at all.
The beauty of the Internet is you need not have a single identity, or one that’s attached to your real name. Pseudonymity isn’t about hiding, it’s about giving yourself permission to be less precious. Just think of a portmanteau about birds, then get the domain and X handle. When it’s @pelicanonical’s side project rather than $FULL_NAME’s side project, the stakes drop.
The worst case isn’t that people notice and hate on you, it’s that nobody notices you at all.
A useful V0 > A useless V1
What inspired me to even write this post was my recent Merchant of Record comparison app. I felt there wasn’t a good way to compare these providers fairly, and so I saw a way I could be helpful. After a few hours of research and code, I had my V0.
Now, instead of releasing it as a small, useful tool, I felt it wasn’t enough to show the world. I proceeded to plan out a full platform to help choose all layers of your stack: auth, analytics, databases, emails - the works. I spent double the time it took me to build the original tool finding the right domain name, creating a logo, picking the perfect theme and brand, and everything else one might need. Luckily, I stopped myself short of spinning up an LLC.
I am drawn to the idea of fixing the world instead of fixing a specific problem. Feature creep is too easy of a rabbit hole to fall into.
And you may ask - why did I need a Merchant of Record? Well but of course, it was for another unfinished project. I spent more hours researching the best Merchant of Record before even finishing the core product. A V0 does not need to worry about global tax remittance. * A V0 needs to worry about validating a problem, pushing the boundaries, and having fun.
It’s OK to ship buggy software
So long as you’re not programming a flight computer or an X-ray machine, papercuts and weird behavior are fine.
As of writing this, React currently has 375 open bugs filed. The oldest of these bugs was opened 12 years ago, and still has people referencing and commenting to this day. While some hardline Qt users might disagree, I’m certainly glad that React shipped before tackling this issue.
Shipping should feel cheap
When something feels cheap, it happens more. When I have an idea, I burn time picking out my full stack, whether I spin up a VPS or go serverless, and a number of other unimportant decisions. The time it takes to ship an initial version of a project should be the time it takes to write the code, and nothing more. You should be spending minimal time setting up infrastructure.
Making shipping cheap translates to two main ideas: Reducing decision overhead and reducing infrastructure overhead.
You should have a default stack that you enjoy using and know very well. When an idea strikes, you can go immediately into building rather than infrastructure research and planning. There’s no need to chase the new technologies unless your focus is to learn them.
Minimizing compute cost and the time it takes to deploy your code will translate to more of your projects seeing the light of day. This doesn’t necessarily mean you choose Vercel because you can get a website up in minutes (though that might be the answer for you). There are a number of ways to make launching a project cheap. One option is resource sharing - let all your projects live in one VPS, one DB, and one domain, at least in the beginning. A single $20 VPS can run a hundred projects at once. Shipping a new project should be as quick as moving new code onto a machine.
Making something feel cheap is not an easy task, but it’s a worthwhile one if you want to launch more software.
Time to ship
So I say it’s high time that I finally ship something to the world. Something that is imperfcet and unfini