Why your MVP estimate is wrong: how I scope freelance projects to avoid rework
I lost a week on a recent SaaS project because I built exactly what the client described in the first email. Here is how I now scope MVPs by defining non-goals, mapping the happy path, and setting clear change-request protocols to protect the timeline and the relationship.

Context
I lost a week on a recent SaaS project because I built exactly what the client described in the first email. The result was a mess of conflicting requirements: the client wanted a dashboard but described a reporting tool. I spent three days building the wrong thing before we had a proper kickoff.
This is the most common failure mode in freelance work. Clients think they know what they want, but they usually don't. My job is not just to code; it's to translate vague ideas into a buildable spec. When a client says "build me a CRM", they mean different things. One wants contact management, another wants sales pipeline tracking, another wants email integration. If you start coding on the first sentence, you'll be stuck in a loop of changes.
I used to write estimates based on the features listed. I'd say "this is five days." Then the client added "oh, we need multi-tenancy" - another two days. Then "and role-based access control" - another three days. The estimate doubled but the timeline didn't. The client felt burned, I felt overworked, and the relationship suffered. The fix is to define the boundary before the code - define the non-goals.
What I do
My current process relies on three specific steps that I execute before writing a single line of code.
1. Define the non-goals The most important part of scoping is what you are not doing. I ask every client to list three things they definitely do not want in the MVP. It sounds counterintuitive, but it forces clarity.
For example, a client wanted a job board. I asked what they did not want. They said "no resume uploads", "no chat system", and "no admin panel for editing jobs". That meant I could build a simple list view with a form. No database for files, no real-time messaging, no complex admin CRUD.
The estimate dropped from 12 days to 5. The client got the core function faster. I didn't have to build features they didn't need yet. The non-goals document is my safety net. If they ask for chat in week two, I point to the document. We can discuss it, but it's out of scope for now.
2. Map the happy path Clients often describe exception cases first. "What if the user is offline? What if the API fails?" These are important, but not the MVP. I map the happy path: user logs in, sees list, clicks an item, sees details, clicks submit, sees success. That's it. Everything else is edge case handling.
I build the happy path first, test it, show it to the client. Then we talk about edge cases. This prevents me from spending days on error handling for a feature that might change. It also gives the client something tangible to critique. I use a simple flow diagram for this: boxes and arrows, no code. The client sees the flow and can say "wait, I need to go back to step two." That's a cheap change. It becomes expensive if I have already built the routing.
3. Set the change-request protocol Even with good scoping, changes happen. Clients see the UI and think of new ideas. I have a clear change-request process. If a change is small, I do it. If it's large, I give a new estimate.
I define "small" and "large" in the contract. Small is less than half a day of work. Large is more. This removes emotion. The client doesn't feel I'm being difficult; I am just following the process. They don't feel I'm padding hours; I am just quoting the time.
I use a simple template for change requests: "Feature: X. Impact: Y days. New total: Z days. Approve or decline?" This keeps the conversation focused on cost and benefit. It stops "can you just add this quickly" requests that eat your week.
Tradeoffs
This method requires upfront effort that might feel slow compared to jumping straight into code. You are trading immediate coding hours for clarity hours. However, the tradeoff is significant: you avoid the exponential cost of rework.
There is also a tradeoff in precision. I do not write 20-page specs listing every button, field, and error message. That is a waste of time because the client will change their mind, rendering the spec outdated before you start. Instead, I focus on flow and boundaries. Details emerge during the build. You can adjust the UI without breaking core logic. By keeping the spec lean, I accept some ambiguity in the visual details in exchange for certainty in the functional boundaries. This ensures that when changes happen, they are manageable adjustments rather than complete rewrites.
FAQ
How do I handle a client who refuses to define non-goals? If a client refuses to define non-goals, I assume they want everything. I quote accordingly, add a buffer for changes, and set a hard deadline. If they miss the deadline, the project slips. This is not a threat; it's a reality. If they cannot define what they don't want, I can't promise fast delivery. I communicate this clearly: "If we don't define scope, the timeline will be flexible." Most clients will then define scope to get a fixed date.
Why not just build the skeleton and show them? You should, but only after mapping the happy path. If you build the flow in your head and show them the finished product, they'll have opinions. Show the skeleton first. Early feedback is cheap. Late feedback is expensive. Always show the skeleton before the skin. This ensures that the structural logic is sound before you spend time on the "skin" or UI polish.
Bottom line
Scoping is not about controlling the client; it's about protecting the project. Define the non-goals. Map the happy path. Set a change-request protocol. Do this before you write a line of code. You'll save time, money, and build better relationships. The code will be better because you know what you're building. Start with boundaries, then build the thing. It is that simple.
Sponsored
Ali Hamza is a full-stack developer in Lahore specializing in MERN, Next.js, and AWS serverless.
Free resource: viral packaging checklist · products
Want this built for your product?
Hire me for production Next.js, MERN, and AWS work. Prefer a short call over a long thread.