One Codebase, Multiple Brands
SaaS products are often sold under multiple brands — same features, different logo, colors, and app name. Copy-pasting the repo per customer does not scale.
White-labeling swaps presentation via configuration while feature code stays identical.
Vocabulary
| Term | Meaning |
|---|---|
| Build-time switch | Env var picks assets before yarn build — one deploy per brand |
| Runtime switch | Fetch brand config after load — one deploy for all brands |
| Alias | Bundler shortcut like @tokens that resolves to a brand-specific file |
Build-time vs runtime
| Build-time | Runtime | |
|---|---|---|
| Speed | Fast — static CDN bundles | Slower — config fetch on load |
| Deploys | One per brand | One for all brands |
| Risk | Must rebuild to change brand | Flash of wrong brand possible |
Most design-system-heavy apps use build-time for colors/logos and a config object for text metadata.
Steps
Step 1 — Set the brand env var
Step 2 — Wire Vite aliases
The bundler maps generic import paths to brand-specific folders:
Components import @tokens and @brand-assets — never a hard-coded logo path.
Step 3 — Define brand metadata
App name, owner, and social links live in a typed config record:
Step 4 — Import brand assets
Checklist — add a new brand
- Copy token CSS file, adjust palette
- Add asset folder with logos and icons
- Add entry to brand config
- Allow the new ID in the brand type union
- Rebuild with
BRAND=NEWBRAND yarn build
Common pitfalls
- Hard-coding logo paths in components — breaks multi-brand.
- Forgetting to restart dev server after changing
BRAND. - Mixing i18n translation files with brand metadata — keep them separate.
Verify it works
Change BRAND, restart dev. Colors and metadata should swap. Components should need zero edits.
Takeaway
White-label is configuration, not duplication. One env var, two aliases, three files per brand — features untouched.