How I Run a Product Team of One
Solo builders skip process to move fast. Here's why that's the trade-off you can't afford.
The myth of moving fast alone
There’s a version of solo building that sounds like freedom. No standups. No stakeholders. No process. Just you, your editor, and a deployment pipeline.
I’ve lived that version. It’s not freedom. It’s just undocumented risk.
I’m building RoleNavigator while running a consulting practice. Every hour I spend on product is an hour I’ve chosen over something else. Speed matters. But I’ve also shipped features that looked done and weren’t, caught bugs that would have hit real users, and watched a single missing database constraint nearly loop every new user through onboarding forever. Not because I’m a careless builder. Because complexity compounds faster than memory does, and “I’ll remember to check that” is not a process.
What follows is what I actually do now, and why I do it.
Every feature gets a written plan before a single line of code
I used to start building the moment I understood the problem well enough to start. That felt efficient. It wasn’t.
Now every meaningful feature starts with a written plan: the tasks, the sequence, the dependencies, and the acceptance criteria for each piece before the first task is dispatched. Not a novel. A document I can hold myself accountable to.
The plan does something that feels counterintuitive: it makes scope additions visible. When I have a clear task list and I want to add something mid-build, I have to decide where it goes, what it touches, and whether it belongs in this release. That friction is the point. Mid-build scope additions that don’t get formally acknowledged get lost. They get built halfway, or they conflict with something already in flight, or they get “confirmed” by a reply that never actually reflected the current state of the work.
Writing the plan doesn’t slow the build down. It moves the confusion to the front, where it’s cheap to resolve.
Reviews happen at every task boundary, not at the end
The most common thing I hear from builders who skip review cycles is some version of: “I know what I built, why would I review it?”
Because you don’t, actually. Not completely. Not the edges.
I run a two-stage review at every task boundary: a task-level review of what was just built, then a scoped re-review of any fixes that came out of it. The task review isn’t asking “does this work?” It’s asking “what is this actually doing, and what happens at the boundary conditions I didn’t test?”
In a recent onboarding redesign for RoleNavigator, this process caught a funnel event that could double-count on back-navigation and refresh, an analytics event inflated up to 15x by a background polling process, and a failed-save condition that swept users forward with nothing actually persisted. All of these passed every automated test. None of them were obvious. All of them would have shipped.
The reviews don’t have to be long. They have to be real. “Does it work on the happy path?” isn’t a review. “What happens when the user refreshes here, or navigates back, or hits this endpoint twice?” is.
The test suite is not the whole safety net
I run a substantial automated test suite. It gives me real confidence. It is not a substitute for running real flows against a real environment.
Here’s the specific failure that made this non-negotiable: I was using SQLite for local test runs. SQLite handles certain database operations differently than Postgres. In one release, a database table I’d added couldn’t accept a single row in real Postgres due to a SQLite-specific assumption baked into the schema. The test suite, all 3,400+ tests, passed. The bug was silently swallowed in the app layer, and the swallow corrupted the surrounding transaction, causing a cascade that would have re-routed every new user through onboarding in an infinite loop.
It was caught only by running real HTTP flows against real Postgres before deployment.
The principle I’ve taken from this: the test suite tells you the code does what you think it does. A real-environment walkthrough tells you the system does what you think it does. Both matter. Neither replaces the other.
Human eyes catch what automated tools can’t reach
Two of the sharpest bugs in a recent release were CSS state issues found on a phone. One was a hover state visually identical to a selection state, which on touch devices with sticky hover behavior made it appear that the previous answer was still selected on the next question. The other was a layout issue in a form element that lived in a browser default stylesheet, not in my code, that no JavaScript-layer test could have surfaced.
The phone is part of the toolchain. Not as an afterthought at the end, but as a deliberate step before anything ships.
This is one of the places where building alone is genuinely harder than building on a team. On a team, you have people using the thing at different stages. Alone, you have to build the habit of being your own user, on the actual devices your users have, before you decide it’s done.
Process failures that stall work are worth naming explicitly
Building with AI agents has changed how I work in real ways, and it’s introduced a category of failure I had to learn to name: finish-line stalls. A task completes, but the result never gets committed, reported, or handed off. Work disappears into a state that looks done but isn’t recoverable.
The fixes that actually stuck: commit and report on targeted success, not at the end of the whole sequence. Run trailing verification after fixes, not just after the original build. Size deadlines to expected time plus buffer, and treat a stalled process as a stalled process, not as progress that’s about to resume.
The broader version of this applies to any solo workflow, with or without AI. Incomplete handoffs between your “building” mode and your “reviewing” mode lose work. Treating a half-finished piece as done because you understand the intent is how bugs get promoted to production.
Mode switching is a discipline, not a personality
The hardest part of running a product team of one isn’t the building. It’s the mode switching.
When I’m building, I need to move. When I’m reviewing, I need to slow down and be adversarial toward my own work. When I’m planning, I need to be honest about what I don’t know yet. When I’m doing a walkthrough, I need to be a user, not a builder.
These modes are in tension with each other. The builder in me wants to skip the review because it slows momentum. The reviewer in me wants to expand scope because there’s always one more thing. Managing that tension deliberately, not just hoping it balances out, is what makes the process repeatable.
The version of solo building that sounds like freedom is the one where you don’t have to manage that tension. In my experience, that version ships more, and ships worse.
What “done” actually means
I’ve landed on a definition of done that has three gates: the task review passes, the full suite is green in the canonical environment, and I’ve walked a real flow end to end.
That’s it. Not “I think it’s right.” Not “the tests pass.” All three.
It adds time. Less time than debugging a production issue. Less time than explaining to a user why they hit a broken state. Less time than shipping something that looked done and wasn’t.
The process isn’t the opposite of moving fast. It’s what makes moving fast sustainable.