Skip to content

Make it yours

Do these once, before your first feature.

You can read the kit’s repository but not push to it. Keep the kit as a second remote, called upstream, to take updates from:

Terminal window
git clone https://github.com/Michael-Guay/saas-stack.git my-product
cd my-product
git remote rename origin upstream
git remote add origin https://github.com/<you>/<my-product>.git
git push -u origin main

Make the new repository private: the licence lets you build any number of products, not pass the kit on.

To take an update:

Terminal window
git fetch upstream
git merge upstream/main

Expect conflicts in files you have both changed. They stay few when your features live in folders of their own, as in Add a resource.

Before you merge, read the new entries in the kit’s UPGRADING.md: what changed, and what you have to do. Or ask your coding agent to “upgrade the kit”: the upgrade-kit skill does the merge on a branch, follows those notes, and tells you what is left for you.

The name is in five places, and the tagline beside it:

Where What it names
packages/contracts/src/app.ts appConfig.name: the sidebar and every email
packages/contracts/src/app.ts appConfig.tagline: one line beside sign-in and sign-up
apps/web/index.html The browser tab, in <title>
apps/site/src/config.ts The marketing site: name, tagline, description
apps/mobile/app.json The mobile app: name, slug, scheme, store identifiers
MAIL_FROM in .env Who your emails come from

If you change the mobile app’s scheme, set MOBILE_SCHEME to the same value: the API accepts sign-in from the app by it.

Replace favicon.svg in apps/web/public and apps/site/public too. In your own code, write appConfig.name, never the name itself.

The palette is warm paper and ink, with one accent color, --brand (marigold). Buttons and other actions are --primary: ink on paper, and paper in dark mode, with --primary-foreground on top. The accent marks things (meters, progress, the logo) and never sits behind words. Headings use Instrument Sans set tight (the font-display class), as does text, and labels and code use JetBrains Mono.

The colors are in four places. Change them together:

Where What
apps/web/src/styles.css The tokens, light and dark
apps/site/src/styles/global.css The same tokens, for the site
apps/mobile/src/theme.ts The same, as hex for React Native
apps/api/src/mail/templates/layout.tsx The emails, which use light only

The share images in apps/site/src/lib/og.ts and the favicons use them too. Every place the look lives, logo and icons included, is in Change the design, and the redesign skill changes them all at once.

One setting, in packages/contracts/src/app.ts:

export const appConfig: AppConfig = {
name: 'Acme',
teams: false,
};
teams People get Addresses
false, as it comes An account of their own, straight into the app /app/settings/billing
true Workspaces they create and invite others to, with roles /w/acme/settings/billing

Either way, everything people create belongs to a workspace. With teams off, each person has one they never see. Build every feature against the workspace and it works in both modes: see Workspaces and teams.

You can start with false and turn teams on later: people keep their data, their addresses change to /w/user-<id>/..., and old /app links stop working. Going from teams back to personal accounts is not supported once people share workspaces. Turning teams on has not been tested beyond reading the code.

Per-seat pricing only makes sense with teams on. See Charge for a feature.

AUTH_SECRET signs session cookies. Everyone who has the kit knows the one in .env.example, so generate yours:

Terminal window
openssl rand -base64 32

Put it in .env. Changing it signs everyone out. Production needs another one again, and the API refuses to start in production with the example value.

Start your product: describe it to your coding agent, and it plans what to build on the kit before it writes any code.