# The Hidden Cost of Building from Scratch: How Kits Save Weeks, Not Hours

> Revealing the real time tax of building auth, databases, payments, and more - and how kits change the game
> By Dave · 2026-07-08
> Source: https://otf-kit.dev/blog/the-boilerplate-tax

The best thing about solo building is also the worst part: every decision is yours, including the ones that have nothing to do with your product. The first two weeks of a new project are usually a tax on the other 90% — and that tax is what kills more side projects than bad ideas ever do.



![15-day build from scratch vs 2-day ship with a kit](https://cdn.otf-kit.dev/blog/the-boilerplate-tax/inline-1.png)



## The cost, itemized

I'm going to name the five layers out loud and put honest numbers on each, because the boilerplate tax is one of those things everyone complains about and nobody actually adds up.

**1. Auth.** Email and password, session cookies, password reset, email verification, optional OAuth. If you've done it once, you can do it again in two days. If you haven't, three to four, plus the half-day you spend learning that you shouldn't be rolling your own password hashing — use argon2 with a cost factor tuned to ~250ms on your target hardware. A working implementation isn't the goal; a *correct* one is.

**2. Database layer.** Schema, migrations, a query interface that produces types you can trust in TypeScript, indexes for the queries you'll actually run, a seed script for local dev. Realistically one to two days for a 10-table schema with foreign keys and soft deletes. Add another day if you want row-level security, which you almost certainly should for any multi-tenant app.

**3. Payments.** Stripe Checkout is the easy part. The webhook handler that keeps your subscription state in sync with Stripe's, the customer portal link, the receipt emails, the dunning flow — that's two to three days for the first time, and a full day to test properly with the Stripe CLI replaying events locally. The number of production bugs from "we missed the `invoice.payment_failed` event" is not zero.

**4. Design system.** Tokens, primitives, dark mode, focus rings, accessible defaults, responsive variants. If you already have a system, two to three days to bring it over. If you're building it from scratch — and "design system" usually means the second day you spend arguing with yourself about whether your border-radius is `6px` or `8px` — call it a week. Add another day for the accessibility audit you keep meaning to do.

**5. Deploy pipeline.** Custom domain, DNS, TLS renewal, environment management, preview deploys, mobile build if you need iOS or Android. Web-only: one to two days. Cross-platform: three to five, because the iOS signing and Android build configuration is its own universe, and "works on my machine" stops being a joke the moment a real device is involved.

Add them up honestly:

| Layer            | Solo, first time | Solo, second time | Rush job |
| ---------------- | ---------------- | ----------------- | -------- |
| Auth             | 3                | 2                 | 1        |
| DB layer         | 2                | 1                 | 0.5      |
| Payments         | 3                | 1                 | 1        |
| Design system    | 5                | 2                 | 1        |
| Deploy           | 2                | 1                 | 1        |
| **Total (days)** | **15**           | **7**             | **4.5**  |

That "rush job" column is the optimistic one. It's also the one with the tech debt you'll be paying back for a year.

## The hidden tax

The 15 days is the visible cost. The hidden one is the second-guessing. Every hour you spend on auth is an hour you're not spending on the product. Worse, it's an hour where the most recent thing in your head is "did I get the CSRF token validation right" instead of "is this actually the product I want to ship."

The hidden tax compounds. A solo builder's worst enemy isn't slow progress — it's switching cost. Every time the context shifts from "product" to "infrastructure," the re-entry cost to actually working on the thing only you can build eats another thirty minutes. Five infrastructure layers, that's two and a half hours a day where the work is real but the value isn't.

This is the part nobody puts in a tweet. The boilerplate tax isn't just time. It's cognitive load.

## What a kit actually removes

A good kit removes the *shape* of those five layers. It does not remove your job — and that's the part to be honest about. Here's the split.

**Removed:**

- The auth UI, the session middleware, the password reset flow. You wire env vars, you get a working sign-in.
- The migration runner, the typed query layer, the seed script. You write your schema, you get migrations and types.
- The Stripe webhook handler, the customer portal link, the subscription state machine. You set `STRIPE_SECRET_KEY`, you get billing.
- The design tokens, the primitive components, the dark mode toggle. You write `<Button variant="primary">`, you get a button that matches on every platform.
- The deploy script: custom domain, DNS, TLS, env management, mobile build artifacts. You run one command, you get a URL.

**Left to you, deliberately:**

- Your product's domain model — the part that defines what you're building.
- The features no one else has built yet — the actual moat.
- The decisions only you can make: which Stripe plan to offer, what the trial length should be, which OAuth providers your users actually use.
- Knowing whether the thing is worth shipping in the first place.

The line is sharp. Here's what it looks like in code:

```sql
-- what a kit gives you
create table "user" (
  id text primary key,
  email text unique not null,
  email_verified timestamp,
  image text
);
create table session (
  id text primary key,
  user_id text references "user"(id),
  expires_at timestamp not null
);
create table account (
  id text primary key,
  user_id text references "user"(id),
  provider text not null,
  provider_account_id text not null
);

-- what the kit leaves to you
create table recipe (
  id text primary key,
  user_id text not null references "user"(id),
  title text not null,
  ingredients jsonb not null,
  created_at timestamp not null default now()
);
```

The first three tables are boilerplate. The fourth is your product. A kit should ship the first three; you write the fourth. A kit that ships the fourth for you has stopped being a kit and started being a product you didn't ask for.

## Where the line is (honestly)

Three places a kit can't help you, and shouldn't try to:

1. **Your data model for your product.** A schema for "users, accounts, sessions" is boilerplate. A schema for the actual entities your product reasons about is yours. A good kit gives you the first; a bad one tries to give you both and ends up giving you neither cleanly.
2. **Your pricing.** Stripe Checkout is a kit's job. What you charge, what you bundle, when you raise prices — that's product strategy, not infrastructure.
3. **Your launch.** A deploy script can put you on a domain. It can't decide who to tell, why they'd care, or what the first sentence of your landing page should be.

If a kit is doing any of these for you, you've stopped being a builder and started being a template's customer.

## What this gets you

If the realistic first-time solo cost is 15 days and a kit gets you to 2 — a long afternoon of wiring, plus a few hours of fixing the things specific to your stack — the question is what you do with the 13 days back. The honest answer for most solo builders is: you actually ship.

The trap — and this is the one place I'll use the word — is treating the kit as the product. It's not. The kit is the part you don't have to think about so the part you do think about can take up more of your head.

The split a well-built kit enforces is what you're paying $99 or $149 for, depending on whether you want one full-stack app or every kit in the catalog. That buys you a design system with a 24-item quality checklist enforced before any kit ships, the same component on web and native from one API, Stripe and auth and a deploy script wired to a custom domain in one command, and around 200 components in the free libraries to cover the long tail of pages you'd otherwise build by hand.

None of that is your differentiation, and none of that should eat your second week. Your differentiation is the 90% that comes after the first 10%. The kit's job is to get out of the way of that — and to ship the part of the work that's already been solved, so the part that hasn't gets the hours it deserves.

The boilerplate tax is real, it's measurable, and it's not the part that makes your product worth using. Spend the 15 days if you want to learn every layer from scratch — that's a legitimate path, and you'll come out the other side knowing more than a kit would have taught you. Spend the 2 days if you want to ship. The choice isn't a moral one; it's a calendar one. Either way, be honest about the cost — most "I spent the weekend building X" posts leave out the weekends before the weekend, where the auth and the DB and the deploy got built and then forgotten. Those weekends are the tax. Decide what they're worth to you.