How to rename or rebrand the app so every surface — title, package metadata, PWA manifest, and icons — stays consistent. Use when a prompt establishes or implies a new app name, title, or visual identity, OR when you generate an app title, theme, or icon yourself while scaffolding an app from an initial prompt.
Installs into .claude/skills of the current project.
Are you the author of App Branding?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/builderio-app-branding)
---
name: app-branding
description: >-
How to rename or rebrand the app so every surface — title, package metadata,
PWA manifest, and icons — stays consistent. Use when a prompt establishes or
implies a new app name, title, or visual identity, OR when you generate an app
title, theme, or icon yourself while scaffolding an app from an initial prompt.
scope: dev
metadata:
internal: true
---
# App Branding
## Trigger
Read this skill whenever the app's name, title, or visual identity is being
established or changed — whether the user states it or **you derive it yourself**.
- **Explicit** — the prompt names the app: "rename this app to …", "this is a
Todo app called …", "call this app …".
- **Implicit / agent-generated** — the prompt describes what to build but leaves
the branding to you: "build me a habit tracker", "turn this into a recipe
manager", "make a CRM for my studio". The moment you decide on a title, theme
color, or icon from that prompt, treat it as a branding change and apply the
full checklist so your generated identity lands on every surface — not just
the one screen you happen to be building.
If you are inventing an app title, theme, or icon as part of scaffolding a new
app from an initial prompt, that counts — run the checklist in the same pass.
## Rule
Apply **all** of the updates below in a single consistent pass. Depending on the
template, the app name may live in one source-of-truth module or be spread
across several files — either way, a partial rename leaves the app half-branded
(a stale tab title, launcher label, or icon).
Derive three values once, then reuse them everywhere:
- **Title** — human-readable display name, e.g. `"My Task App"`.
- **Slug** — URL/npm-safe form: lowercase letters, digits, and hyphens only,
e.g. `"my-task-app"`.
- **Description** — one sentence describing what the app does.
## Locate the layout first
Branding lives in different places depending on the template. Detect which
layout you are in before editing:
- **Centralized layout** — `app/lib/app-config.ts` exists. It is the single
source of truth for the name and title; the frontend surfaces (`<title>`,
route `meta()`, header, sidebar, index heading, `apple-mobile-web-app-title`)
derive from its `APP_NAME` / `APP_TITLE` exports, so you change the name in one
place.
- **Inlined layout** — no `app/lib/app-config.ts`. The name and title are
written directly into `package.json`, each route's `meta()`, and
`app/root.tsx`. You must update each surface individually.
When in doubt, `grep -rn` the current title and slug across `app/`, `server/`,
`package.json`, and `public/` and fix every real hit — the two layouts share the
manifest and icon steps regardless.
## The Checklist
### Step 1 — App name + title source
**Centralized layout** (`app/lib/app-config.ts`): change both constants and stop —
the rest of the frontend derives from them.
- `rawAppName` → the **slug**.
- `rawAppTitle` → the **title**.
**Inlined layout** (no `app-config.ts`): set the title/slug at each surface.
- Every route `meta()` title under `app/routes/*.tsx` (e.g. `_index.tsx`,
`agent.tsx`, `settings.tsx`) — replace the app title. These are seeded from a
`{{APP_TITLE}}` placeholder at scaffold time and become plain literals
afterward.
- Any `useActionQuery("hello", { name: … })` in `app/routes/_index.tsx` seeded
with the title.
- `app/root.tsx` `apple-mobile-web-app-title` — a literal (often `"App"`); set it
to the **title**.
### Step 2 — `package.json` (both layouts)
- `displayName` → the **title** (add the field if the template omits it).
- `description` → the **description** (add if absent).
- `name` → the **slug**. Only change this if the user explicitly asks to rename
the package (it is the npm package identifier).
### Step 3 — Login / auth title (centralized layout only)
If `server/plugins/auth.ts` exists it keeps its **own** duplicate `rawAppTitle`,
used on the login/signup pages. Set it to the same **title** as
`app/lib/app-config.ts`. (The inlined layout's `server/middleware/auth.ts`
carries no app title — skip this step there.)
### Step 4 — `public/manifest.json` (both layouts)
This is a static file (not generated by a plugin). Update:
- `name` → the **title** (full install name in OS app drawers).
- `short_name` → a compact launcher label; keep it ≤12 characters, abbreviating
the title if needed.
- `description` → the same **description** used in `package.json`.
### Step 5 — Icon SVG files (both layouts)
Replace the icon files with a new mark that reflects the app's identity. The set
present depends on the template; update each one you find:
| File | Purpose |
| --- | --- |
| `public/favicon.svg` | Browser tab favicon |
| `public/icon-180.svg` | Apple touch icon (iOS home screen) |
| `public/icon-192.svg` | PWA install icon (Android / Chrome) |
| `public/icon-512.svg` | PWA install icon (large / splash) |
Build the icon from **SVG primitives** — do not embed a base64-encoded PNG. All
files should share the same visual design; only the `width` and `height`
attributes differ. A simple, reliable approach: a filled rounded square in the
brand color with the first letter (or a relevant glyph) centered in white.
Template to adapt (change `fill`, the letter/glyph, and `rx` to suit the brand):
```svg
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="192" viewBox="0 0 192 192">
<rect width="192" height="192" rx="40" fill="#2563EB"/>
<text x="96" y="130" font-family="system-ui, sans-serif" font-size="110"
font-weight="700" fill="white" text-anchor="middle">A</text>
</svg>
```
Keep `width`/`height` at `180`, `192`, and `512` for the respective icon files;
`favicon.svg` can use any of these sizes (the `viewBox` keeps it scalable).
## What NOT to change
These are stable identifiers or template-internal files, not user-facing brand:
- `configureTracking({ app, template })` in `app/root.tsx` — analytics
identifiers seeded at scaffold time; leave them. This holds even in the inlined
layout, where `app` was seeded from the slug — changing it re-keys analytics
history.
- `server/plugins/agent-chat.ts` `appId` (centralized layout) — a stable
platform analytics/routing key; leave it exactly as scaffolded.
- `.github/workflows/*.yml` — template automation; references the repo/template
identity, not the running app.
- `AGENTS.md` / `DEVELOPING.md` — developer docs for the template itself.
## Verification
- `pnpm typecheck` passes.
- Grep for the old title/slug across `app/`, `server/`, `package.json`, and
`public/` — no unintended leftovers remain (except the intentional
"do not change" identifiers above).
- The browser tab title, sidebar/header, and index heading all show the new
title.