Your Side Project Doesn't Need to Be Perfect to Ship cover image

Your Side Project Doesn't Need to Be Perfect to Ship

Scott Keck-Warren • August 21, 2026

When I started building Unleashed Podcasts, I hardcoded a bunch of stuff that had no business being hardcoded. Values like XP for publishing an episode, streak rules, and the list of episode statuses lived in a file instead of a settings table anyone could manage.

If you've built anything with a config layer before, you know exactly what I skipped. There was no admin screen for tweaking values, no database table for statuses, and no settings model at all. Just values sitting directly in the code where any reasonable engineer would tell you they don't belong.

I knew that when I wrote it, but I did it anyway.

Why I chose the hacky version on purpose

Unleashed Podcasts is a tool to help podcasters and other content creators stay on a publishing schedule with features like task lists, streaks, XP for hitting milestones, and a content calendar so you can see what's coming up next. The whole point is to reduce friction for creators, and it would have been extremely ironic if I'd spent the first month buried in friction of my own making, building a fully configurable rules engine before a single real user even touched the app.

Building that "correct" version first meant designing a settings schema for values I hadn't validated we needed to be variable yet. Should streak grace periods be configurable per user, or just a global setting? Should XP values differ by content type? I didn't know because nobody had used the app yet, so any answer I picked would have been a guess dressed up as architecture.

So I hardcoded it, shipped it, and got Unleashed Podcasts in front of real people.

I used spec-driven development and AI coding tools to build most of this, and that process made the corner-cutting more deliberate than it sounds. Writing the spec forced me to be explicit about what I was building now versus what I chose to defer. The spec said, "XP values are fixed constants for v1, revisit after usage data." It was a decision, not an oversight. Doing it that way meant Claude (and future me) knew what was temporary and what wasn't, instead of leaving landmines in the codebase by accident (in this case, it's landmines on purpose 😬).

What happened after people used it

A few weeks in, real usage told me things I never would have guessed from a whiteboard. Some creators wanted a softer streak rule because a single missed day felt punishing when "real life" got in the way. Other users wanted higher XP rewards for finishing a full episode versus just drafting show notes, because the flat rate made the smaller tasks feel as rewarding as the big ones, which killed motivation instead of building it.

That's when I went back and built the real config layer that could flex based on user feedback instead of my best guess. The resulting system was better than anything I would have designed upfront, because it was shaped by what people needed instead of what I imagined they might need.

What to cut and what to protect

Cutting corners isn't the same as being careless, and it's worth being honest about the difference. I hardcoded XP values and status lists because getting them wrong was cheap to fix later. Nobody's data got corrupted by a wrong point value. Nobody lost an episode because "editing" wasn't a configurable status yet.

Things I didn't cut were things like authentication, password handling, data validation on anything that touched a user's account or their episode data, and backups. Those aren't the parts you defer, because getting them wrong is expensive or dangerous, not just inconvenient. The rule I like to use is that if a shortcut is hard to reverse or puts someone else's data or security at risk, don't take it. If it's just annoying to refactor later, take it and move on.

Premature configurability, premature abstraction layers, premature "what if we need to scale to a million users" thinking: all fair game to skip on a side project nobody has used yet. You're not protecting against real risk when you build for a scenario that doesn't exist yet (you might just be stalling).

The part where I admit it

Unleashed Podcasts stayed a little messy under the hood for longer than I'd have liked. There were TODO comments about the config system sitting in the codebase for weeks while I focused on getting more creators onto the platform instead. That bothered the part of my brain that wants clean architecture on day one.

But a messy app that real people are using beats a clean one that isn't being used. Side projects seldom die because someone shipped something rough. They die in the polishing phase, when "just one more refactor before I show anyone" turns into six months of nobody ever seeing it. If you've got a side project sitting half-finished because it's not "ready," ask yourself whether you're protecting quality or just avoiding the moment someone else sees it.

Ship the ugly version, and you can fix the rough edges later, once you know which ones matter.