
I have built a lot of impressive-sounding side projects. A real-time multiplayer game. A toy compiler. A trading bot that lost me $40 in paper money and then crashed.
None of them got me a job.
The thing that finally did was embarrassingly boring: a little app that took the chaos of my freelance invoices and turned them into a single PDF a month. No machine learning. No fancy stack. Just a thing that worked, every time, for two years.
That's the part nobody tells you. The project that changes your career usually isn't the one that shows off. It's the one that proves you can finish.
A portfolio project gets you hired when it shows three things: that you can ship something real, that you made deliberate engineering decisions, and that you can talk about the trade-offs. Pick a small problem you actually have, build it end to end, deploy it where strangers can use it, and write down why you built it the way you did. Depth on one finished thing beats five half-built clones.
The flashy projects fail interviews for a simple reason: they're never done.
A senior engineer can smell an abandoned repo from the README. Half the features are TODO comments. The tests folder has one file that says test_placeholder. The last commit is titled "wip" and it's from fourteen months ago.
What that tells the interviewer is: this person likes starting things. The whole reason they're hiring a senior is to find someone who finishes them.
My invoice app was tiny. But it had real users — me, and eventually four other freelancers I knew. It had error handling because real PDFs are cursed and someone always uploads a 0-byte file. It had a deploy pipeline because I got tired of doing it by hand. It had been quietly running in production longer than some of my full-time jobs.
Shipping something small to real users teaches you more than building something huge for nobody.
Photo by Ilya Pavlov on Unsplash
When I walked the hiring manager through it, I didn't lead with the tech. I led with the decisions.
Here's roughly how that conversation went, and why each part landed:
None of these are hard. All of them are the difference between a junior who codes features and a senior who makes calls — the same gap I unpack in the brutal truth about becoming a senior developer. The habits of the engineers who quietly out-deliver everyone come down to exactly this kind of judgment, not raw output.
The interviewer kept asking "why did you do it this way?" and for once I had an answer for every single question, because I'd lived with the consequences of those answers for two years.
Stop trying to pick something impressive. Pick something annoying.
The best side projects come from a small, repeated friction in your own life. You feel the pain, so you understand the problem deeply, and you'll actually keep using the thing — which is the only way it survives long enough to mature.
Here's the filter I use now:
| Bad project idea | Good project idea |
|---|---|
| Clone of a famous app | A tool that fixes your own daily annoyance |
| Needs 10 features to be "real" | Useful at version 0.1 |
| You'd never use it yourself | You'd use it tomorrow |
| Resume bait | Problem bait |
If the idea only exists to look good on a resume, it'll die the moment it stops being fun. If it solves a problem you genuinely have, you'll maintain it through the boring parts — and the boring parts are exactly where the senior-level lessons hide.
Photo by Cathryn Lavery on Unsplash
Finishing is a skill, and it's rarer than you'd think.
For me, "finished" meant: deployed, monitored, and documented well enough that someone else could run it. That last 20% — the deploy, the README, the error states, the empty states — is where most projects die. It's also the only part interviewers actually probe, because it's the part that mirrors real work.
Once it was done, I wrote a short post about one specific decision I got wrong and how I fixed it. Not a tutorial. A confession. That post got more eyes than the project itself, and two of the people who read it were the ones who eventually forwarded my application.
Writing about the project did something building it couldn't: it forced me to understand my own choices well enough to defend them out loud. That's the exact muscle a senior interview tests.
A bit of light automation helped here too — I had a tiny script that posted my weekly progress to a private channel, which kept me honest about whether I was actually moving or just refactoring for comfort.
The funny part is that I almost didn't mention it.
I'd walked into that loop assuming they'd want to grill me on data structures and big-O. I had flashcards. I'd ground through practice problems. And the technical round did have some of that. But the conversation that decided the offer wasn't about algorithms at all — it was the system design round, where they asked me to design "something you've actually built and run."
Most candidates, the interviewer told me later, reach for a hypothetical: a made-up URL shortener, a chat app they read about. The Stack Overflow Developer Survey shows how many engineers learn on the job rather than in a classroom, and a real running system is the cleanest proof of that learning. I reached for my invoice tool, because it was the only system I could describe down to the failure modes without making anything up. When they pushed on "what happens when the PDF generation crashes mid-job," I didn't have to invent an answer. I'd lived that crash. I knew the job got retried, that the retry was idempotent because of the hash key, and that I'd added a dead-letter path after the third time it bit me.
That depth is impossible to fake, and interviewers can tell instantly. A candidate describing a real system they've maintained sounds completely different from one reciting a design they memorized. The specifics, the scar tissue, the slightly embarrassing war stories — that's the signal that you've done the job before, which is the entire thing a senior hire is being checked for.
I left that round and knew it had gone well, not because I'd been clever, but because for once I'd been telling the truth about something I'd really done.
Looking back, the algorithm prep mattered far less than I'd feared, and the boring little app mattered far more than I'd ever have guessed. I'd spent weeks optimizing the part of the interview that everyone optimizes, and the thing that actually moved the needle was two years of quietly maintaining a tool five people used. If I'd known that going in, I'd have spent less time on flashcards and more time making sure I could explain every decision in my own code.
A real system you've run beats a perfect system you've only imagined. Every interviewer can hear the difference.
People assume senior roles want exotic technology. The opposite is usually true.
I built the whole thing on the most boring stack I knew: a standard web framework, a single Postgres database, and a queue I could have replaced with a cron job. Boring tech meant I spent my energy on the problem instead of fighting the tools.
In the interview, that boringness read as maturity. Anyone can chase the newest developer tools. Choosing the dull, reliable option because it lets you ship is a senior instinct, and it's one you can only demonstrate by having actually shipped something dull and reliable.
If you're building the project that proves you can finish, it's worth following along as I write more about the unglamorous habits that quietly move a career forward.
Q: Does the project need a lot of users to count? No. Mine had five, and only one of them paid me in actual gratitude. What matters is that real people used it and hit real edge cases. Five honest users beat five thousand fake ones in a seed script.
Q: Should I use the newest framework to look current? Only if you'd genuinely choose it for the problem. Reaching for new tech to impress usually backfires — you'll get asked a deep question and have no scar tissue to answer it.
Q: How finished is "finished"? Deployed, handles its obvious error cases, and documented well enough that a stranger could run it. If you'd be embarrassed to give someone the URL, it's not done.
Q: What if I don't have an annoying problem to solve? You do — you've just stopped noticing it. Watch yourself for a week and write down every time you mutter "ugh, again." One of those is your project.
The project that gets you hired isn't the one that proves you're clever. It's the one that proves you can take a small problem all the way to the end and live with the consequences.
Build the boring thing. Finish it. Run it in production long enough to get bored of it. Then learn to explain every decision you made along the way.
What's the small annoyance you've been ignoring that could become your most honest piece of work?
Leaving my job wasn't a leap of faith. It was a spreadsheet. Here's the runway math that turned a terrifying gamble into a boring, calculate…

I chased big, audacious goals for years and burned out every time. Then I built my whole life around wins so small they felt like cheating.

I spent years thinking I just wasn't a disciplined person. Then I realized discipline is built, not born. Here's how I actually built mine.

Comments
Sign in to join the conversation
No comments yet. Be the first to share your thoughts!