Why Shells Ships Zero Database Tables
Cody Ballert · September 4, 2026
Every paid SaaS starter hands you a database — accounts, memberships, roles, invitations — for a product nobody has described yet. If your app isn't shaped like that guess, you spend week one deleting code you paid for. Here's the case for shipping none of it, including the parts that argue against me.
Shells is a Next.js and Supabase starter. It ships a working application — sidebar, header, protected routes, session handling, a design system, sign-in that works. And it ships no database tables at all. The supabase/migrations/ folder is empty.
That's the decision this post is about, including the parts of it that argue against me.
What every other starter hands you
Not their marketing — their published schemas and architecture docs. Here's what you inherit on day one:
nextjs/saas-starter(free) —users,teams,team_members,activity_logs,invitations- Makerkit —
accounts,accounts_memberships,roles,role_permissions, subscriptions, invitations, billing customers, notifications - Supastarter — auth tables, plus organizations, members, roles, purchases
- Achromatic — auth, plus organizations, memberships, roles, subscriptions, usage credits
- TurboStarter — auth, plus organizations/teams and billing
- Boilerplate-Stack — auth, plus workspaces, dynamic roles and permissions, a CMS, credits
- SaaS Pegasus —
CustomUser,Team,Membership, Stripe models - ShipFast — a User model
Every one is a competent, professionally-designed tenancy model. Every one was designed before anybody knew what you were building.
A schema is a guess
Look at what those tables assert about your product: that it has organizations. That people belong to more than one. That membership carries a role. That roles map to permissions. That users are invited by other users. That billing attaches to the organization, not the person.
Six product decisions, made for you, by someone who has never heard of your app.
If you're building B2B SaaS with teams, that guess is close and you saved a real week. That's why these products sell. But if you're building a single-player tool, an internal app, or a marketplace where the two sides are nothing like "members of an org", the guess is wrong — and a wrong guess isn't neutral. You have to go remove it, in a codebase you've owned for four hours, where the auth flow, the middleware, the layout and half the components already reference it.
The category's own customers put it better than I can:
"I just spent the last 48 hours ripping out code from a client's app that was built using one of those popular $300 Next.js SaaS starter kits."
"You didn't save time. You bought a ticking time bomb."
Even a competitor's own maintainer says it out loud, in that same thread:
"don't buy a shitty bloated starter kit that impresses with a feature list that you never really need."
He sells one of the products in that list. He's right anyway.
The best argument against this
Here it is in its strongest form, because it's good and you'll hear it from people with better landing pages than mine: an empty database doesn't make the schema problem go away, it moves it onto your AI agent — and agents are bad at this. TurboStarter's whole headline is the argument, "Give agents real code. Not a blank repo." Supastarter runs the long version:
"Don't let an agent invent your login system… Organizations, invites, and roles are already modeled so agents extend them instead of inventing a tenancy scheme."
And Makerkit: "AI scaffolds a prototype. It can't give you secure multi-tenancy, real billing, or an upgrade path that lasts."
All of that is true, and underrated. Hand an agent an empty repo and a one-paragraph prompt and you'll get a different architecture every session, each plausible, none consistent with the last.
Where I part ways is the conclusion. They're describing what happens when an agent guesses, then offering a pre-made guess as the alternative. Both are guesses. One is just yours.
The third option is that nobody guesses — the schema gets decided in a conversation with the person who knows the product, before a line of SQL is written. That's the /kickoff skill, and it's a post of its own: an interview, not a prompt.
The empty database isn't the absence of a decision. It's what makes the decision available to you.
What Shells ships instead
"Blank" is doing a lot of work in that rebuttal. What's actually in the repo: the application chrome — collapsible sidebar, route-derived breadcrumb, a page sub-nav that collapses on small screens, sidebar state persisted in a cookie so it doesn't flash on load, and navigation as data, where adding a page is a route and one array entry. Auth that works — Supabase SSR clients, protected-by-default routing with a public allowlist, the session resolved on the server before first paint, and sign-in, sign-out, password reset, update password, OAuth and magic-link callback all implemented. A design system with a point of view. And a demo mode that renders the whole application against a hardcoded session with no Supabase environment variables at all, so you can look at the thing before connecting anything to it.
What's missing is the layer that encodes what your product is. That's the only thing missing, and it's missing on purpose.
The honest version of the claim
Zero tables is unique among paid starters. It is not unique absolutely. The official vercel/next.js Supabase example ships no migrations either — auth and nothing else. If your reaction is "the free template already does that," you're right. It also ships no chrome, no design system, no agent tooling and no interview. For some projects that's still the correct choice.
And "setup isn't the hard part anymore" is a fair hit. Claude Code can scaffold a sidebar in one ask. But you know what one ask produces: a structure the agent invented, different next session, that you review as carefully as if a stranger wrote it. The disagreement isn't about whether an agent can. It's about whether you want the shape of your application re-decided every time you open a new chat.
What this costs you
You have to show up for the conversation. Shells doesn't hand you a schema, but it doesn't leave you to draw one either — /kickoff asks the questions and the agent writes the migration and the policies from your answers. You're not doing database design. What you can't outsource is knowing your own product: whether a record can belong to two groups, whether an admin of one workspace sees anything in another. That's half an hour of product thinking, and it decides the data model either way — the only question is whether you spend it now, on purpose, or in week six, on a rewrite.
There's no sign-up screen. Shells ships sign-in, not registration; your first users are created in the Supabase dashboard. Self-serve, invite-only and admin-provisioned are three different products, and picking one for you would be exactly the guess this post objects to.
No tests, no CI, light mode only. Each is deliberate, and each is a real thing you don't get.
What you start with instead
An empty folder — the part of this that's hardest to appreciate before you've used it. Everything else follows from it: a conversation can only decide something that hasn't already been decided. The interview is real because its answers are load-bearing.
And if your product turns out to be org-shaped after all, you'll write those tables in week one. They'll carry your names for things, scoped the way your product actually scopes, with the columns you use and none of the ones you don't. Same week of work. Minus the week of deleting.
That's the trade. Not less code — code that's about your product.