SsuperslateDocs

Customization

Make the boilerplate your product while preserving its architecture and safety boundaries.

Customization contract

Customize the generated product in layers. Preserve the architecture and verification boundaries that make later agent work predictable; replace the product decisions that are intentionally neutral.

Start from a generated repository

Use create-app once to establish the product name, npm scope, display brand, unique Better Auth secret, and independent Git history. Do not build a product inside the delivered foundation checkout and do not run the scaffolder over an existing repository.

The initial brand replacement is deliberately narrow. It does not choose a commercial name, domain, logo, customer promise, sender, legal entity, support channel, or accessible palette. The optional Customize branding and design tokens playbook provides a maintained route for those changes. No domain, provider account, package registry, or permanent organization may be reserved without an explicit product decision.

Customization map

Product decisionPrimary surfacesPreserve
Name and runtime identityBRAND_NAME in apps/web/src/configs/config.ts and apps/docs/lib/shared.ts, static metadata, PWA manifest, email sourcecounted brand manifest, context-safe replacement, text-free mark
Customer outcome and copyweb metadata, auth/settings states, empty/error states, email copyaccurate capability claims, actionable failures, no inherited example behavior
Visual systemapps/web/src/styles/_variables.css, CSS Modules, local font/image assetssemantic token names, focus-visible, contrast, reduced motion, responsive states
Durable product capabilitymigration, shared Zod contract, server repository/service/routes, web service/moduleownership in SQL, layer boundaries, Hono RPC types, negative-path tests
Authentication optionstyped server environment, apps/server/src/lib/auth.ts, login UIBetter Auth as sole session authority, atomic provider configuration, cookie/origin rules
Legal policy linksVITE_TERMS_URL, VITE_PRIVACY_URL, login acknowledgmentreal public URLs, no placeholder legal claims
Plans and paid accesspackages/contracts/src/billing.ts, selected provider adapter, entitlement service, settings UIprovider normalization, server-side gates, webhook idempotency/order
Transactional communicationpackages/email/src, rendered server templates, mailer/event handlerstyped template inventory, escaping, local fallback, generated-artifact workflow
Public upload typesshared upload contract, upload domain, storage adapters, web upload service/UIowner-scoped claims, metadata confirmation, expiry, size/type enforcement
Optional integration removalfull inventory in Removing subsystemsno dead keys/routes/packages/claims; fresh-buyer proof
Production topologyRailway or Dokploy API/Postgres, Vercel SPA, provider environment, health/readinesssupported target only after equivalent build, proxy, backup, rollback, and smoke evidence

For product behavior, Add a domain end to end is an optional tested playbook. A different implementation is valid when it preserves the architecture and passes verification. A nearby component or route is an example of shape, not permission to skip ownership, validation, loading, error, migration, or security decisions.

Generated and source-owned files

Do not edit generated files manually:

  • apps/server/email-templates/*.html comes from packages/email/src;
  • pnpm-lock.yaml comes from the package manager;
  • database migration history comes from dbmate migration files, not direct production edits;
  • production bundles, PWA service workers, source maps, and the compiled server come from builds;
  • favicon raster variants come from a reviewed source asset and image-generation workflow.

Source ownership means a buyer may fork any code. It does not make every fork part of the supported foundation contract. Record deliberate architecture departures in a local decision file so a later agent knows which upstream assumptions no longer apply.

Product-specific files

Keep product behavior easy to distinguish from the foundation:

  • create a domain rather than adding business SQL to a generic route;
  • keep product-specific constants, copy, events, and policies in the owning domain/module;
  • add a migration instead of editing the released baseline;
  • add local documentation for non-obvious invariants and external resources;
  • keep provider-specific types inside the provider adapter;
  • add tests that describe the product's owner, lifecycle, limits, and failure behavior.

Do not rename every architecture term to match a brand. Stable names such as service, repository, contracts, sessionAuth, and semantic design tokens are navigation aids for people and agents.

Verification

For every material customization:

vp check
vp run -r test
vp run -r build
pnpm audit --audit-level high
git diff --check

Add real Postgres integration tests for persistence/auth/billing/upload changes. Regenerate and inspect email HTML after email changes. Inspect the production PWA and browser states after identity or design changes. Exercise the selected supported Railway/Vercel or Dokploy/Vercel path after topology, origin, cookie, or environment changes.

Before release, generate a second custom-scope/custom-brand reference app from the exact foundation version. A foundation defect reproduces there; a product-only defect does not. Preserve that distinction when requesting support.

Completion criteria

  • The application has one accurate identity and no neutral placeholder or source-product behavior.
  • Product domains preserve contract, route, service, repository, ownership, and migration boundaries.
  • Generated artifacts match their source and the lockfile is frozen.
  • Optional integrations are either configured atomically, visibly unavailable, or removed as a complete vertical slice.
  • Checks, tests, builds, dependency audit, relevant provider flows, and rendered states pass.
  • Local decision records explain intentional departures that will affect future upgrades.

On this page