Guides / 2026-09-08
Why every feature in this template is deletable
A starter you delete from is more useful than one you add to — but only if deleting is a recipe rather than an archaeology dig.

Most SaaS starters are judged by what they include. That is the wrong axis. You will use maybe half of any starter's features, and the half you do not use is not free: it is schema you migrate, code you typecheck, dependencies you patch, and surface area you have to understand before you can safely change anything near it.
So the rule here is the opposite one: every optional feature must be removable in minutes, by a recipe, without leaving a trace.
What that forces
It turns out you cannot bolt deletability on afterwards. It constrains the architecture from the first commit:
- Features are vertical slices.
src/features/<name>/owns its schema, its server functions, its queries and its components. Nothing in one feature imports from another — shared ground lives insrc/core/. - Registration is one line. A feature does not get wired in from ten places. It exports a handler and adds a single import line to a registry: the schema barrel, the payment handlers, the stats providers, the admin user-detail sections, the cron jobs. Deleting a feature is deleting those lines.
- Registries are lazy and tolerant of being empty.
audit()with no sink registered is a no-op, not a crash. That is what lets you delete the audit feature while a dozen call sites keep calling it. - Anything that cannot be one line is fenced. Where a feature genuinely has
to touch shared UI — a sidebar row, a dashboard card — the block sits between
[feature: name] startandendcomments so a recipe can cut it out exactly.
The part that keeps it true
A documented recipe rots the first time someone renames a file. So the recipes
are executable: bun run verify:deletion copies the repo, performs each
deletion for real, and requires typecheck and build to pass afterwards. It runs
on every pull request.
That job has caught recipe rot more than once — a moved import, a new registration nobody remembered to document. Which is the point: the claim on the landing page is only worth making because a machine re-checks it every time the code changes.
ShipKit
