The Only Way to Know If Something Is Wrong Is to Ship It

I'm a Pakistani teenager with a passion for web development and automation
There's a version of perfectionism that feels productive. You're thinking about edge cases. You're considering UX. You're imagining the user. It feels like diligence. It's not. It's just fear with better PR.
I've shipped enough things now to have a working opinion on this: the best way to learn what's wrong with something is to put it in front of real people and let them tell you. Not simulate it. Not imagine it. Actually ship it, watch what happens, and then fix what breaks.
I don't think this is a hot take. But I don't think people fully commit to it, so I want to walk through what it actually looks like in practice.
The Proof Is In The Using
When I built location filtering for JobOps job searches, I thought it was clear enough. You configure a location target, run a pipeline, and it filters accordingly. Pretty straightforward in my head.
But when users started using it, I started getting the same question in different forms. How do I search around a specific city? How do I target a whole region instead of one place? How do I find remote jobs, but only remote jobs based in the US? The details changed, but the underlying question was always the same: how do I configure this thing so it searches the way I actually mean?
The pattern was obvious once I saw it across multiple people. The mental model I had built the feature around didn't match what users intuitively expected. It's not a bug per se, but it is a gap between the product and the person using it.
I couldn't have fixed this by thinking harder before shipping. There's no amount of pre-launch thinking that gives you that data. You get it from users, and you only get users by shipping.
So in a recent PR, I fixed it. Not by rethinking it from scratch, just by closing the gap between what the feature did and what people expected it to do.
The Resume Studio
The same story, but for a different feature.
I shipped a resume designer in JobOps. It worked and you could edit your CV, regenerate it, download it. MVP by any definition of the word. The renderer was slow, the themes were limited, mobile was rough around the edges.
But it was out there. People were using it. And because they were using it, I started understanding what mattered to them about it.
Turns out: speed of rendering is a real friction point when you're trying to quickly tailor a CV before an application. Using tectonic for latex rendering is just too slow, often taking up to 10 seconds for every refresh.
And design quality matters more than I'd weighted it because this is a document you're sending to employers. It's something that reflects on the user and their personality. That context only became obvious once real people were doing real things with it.
So now I'm rebuilding it properly. Faster renderer with Typst, more themes (again enabled by Typst), proper mobile and desktop experience. I know what to build because I shipped the version that got data from real users about what they want.
The Email Timeline
The post-application email tracking feature in JobOps is probably the best example of this pattern.
I built it as a proof of concept, honestly not sure if anyone would care. Connect your Gmail, JobOps will watch for recruiter emails, match them back to job applications. The logic was sound but the UI was bare. I shipped it expecting to learn whether it was even worth building properly.
The feature is a smashing success, and is one of the most configured "optional extra" features in the app, with more than 300 connections in the last 30 days.
I can't imagine people were loving the UI, which was MVP at best. They were loving the idea. The concept of having an automatic and reliable timeline of everything that happened post-application, pulling context from across apps. Instead of having to manually hunt through inboxes and spreadsheets. That concept validated itself through actual usage, not through any planning I'd done.
So now I'm rebuilding that too. The underlying feature proved itself, so now I know it deserves the investment.
What This Actually Means
This isn't a philosophy about shipping broken things and calling it agile. The things I shipped worked. The location filter filtered. The resume designer generated PDFs. The Tracking Inbox tracked emails.
The bar for "good enough to ship" is: does it do the thing? Can a user use it without it actively breaking on them?
If yes, ship it. Not because you don't care about quality, but because the feedback loop you get from real usage is worth more than any additional pre-launch refinement you could do.
The alternative is spending weeks polishing something in isolation, only to learn after the fact that you optimised the wrong part entirely. That's happened to me too, and it's a worse outcome.
A Pattern Worth Naming
Looking at the three features above, there's a consistent structure:
Build something that works. Ship it. Watch what people do with it. Fix what causes friction. Invest properly in the parts that prove they deserve it.
Step two is the one people skip. They either don't ship at all, or they ship and don't watch. Both are expensive mistakes.
If you have users, you have a feedback mechanism that no amount of design thinking can replicate. Use it.
JobOps is an open-source, self-hosted job search tool. If you want to follow along as I rebuild the bits I'm not happy with: github.com/DaKheera47/job-ops



