"Move fast now, we'll clean it up later" is one of the most expensive sentences in software. The cleanup rarely happens on schedule, and by the time a product finds traction, the shortcuts taken to launch it have hardened into the exact things that slow the team down. We've inherited enough of these codebases to have strong opinions about it.

But the opposite instinct — over-engineering a first version for imaginary scale — is just as costly. It burns runway building for users who may never arrive. The goal isn't to choose between speed and quality. It's to be deliberate about where you spend each.

An MVP is a hypothesis, not a tiny version of the final product

The most useful reframe we give founders is this: your MVP exists to answer a question. Usually it's "will people use this to solve the problem we think they have?" Everything that helps answer that question fast is worth doing. Everything that doesn't is a candidate to defer.

That framing changes scope conversations. Instead of arguing about whether a feature is "in or out," we ask whether it's load-bearing for the hypothesis. A referral system, granular admin permissions, and five payment providers usually aren't. A reliable core workflow and a way to talk to real users always are.

Where we never cut corners

Some decisions are cheap to make well now and painful to change later. We treat these as non-negotiable even in a first version:

  • Data model. Renaming a button is trivial; restructuring how core entities relate after you have production data is not. We spend real time here up front.
  • Clear boundaries. Even in a small codebase, we keep business logic separated from framework and UI code. It costs little on day one and means features can move without a domino effect.
  • Authentication and basic security. These are hard to retrofit and expensive to get wrong. We use proven solutions rather than inventing our own.
  • Observability. Basic logging and error tracking from day one. You cannot improve what you can't see, and early bugs are cheapest to fix when you can actually find them.

Where we happily move fast

Just as important is naming what can be simple. In an MVP we're comfortable with a modest monolith instead of microservices, a managed database instead of a bespoke data layer, off-the-shelf UI components instead of a custom design system, and manual internal processes instead of building admin tooling for a team of two. These are reversible decisions. When traffic or team size justifies more, we upgrade them — and because the boundaries above are clean, those upgrades stay contained.

"Production-minded", not "production-heavy"

The phrase we use internally is production-minded. It means writing the first version as if it might succeed — because sometimes it does, faster than anyone expected — without gold-plating it. Concretely: sensible naming, small and testable functions, a handful of tests around the riskiest logic, and a deployment that anyone on the team can run. None of this slows an MVP down meaningfully. All of it means that if the hypothesis is validated, version two is an evolution rather than an archaeology project.

Ship, measure, then decide what's next

The last piece is discipline after launch. We instrument the core flow so we can see what people actually do, not what we hoped they'd do. That data — plus conversations with early users — decides what gets built next. It's a far better roadmap than a feature list written before anyone touched the product.

Done this way, an MVP is not a throwaway. It's the honest first chapter of a product that can grow without stopping to rebuild its foundation.