add-mobile-screen
Add a screen, tab or component to the Expo app (apps/mobile). Use when the user wants something new in the mobile app, or a web feature brought to mobile.
SKILL.md.claude/skills/add-mobile-screen/SKILL.md
GitHubAdd a mobile screen
Same API client and translations as the web app, its own primitives.
.claude/rules/mobile.md and apps/mobile/CLAUDE.md have the rules.
- Data. Hooks from
@repo/client/api/<area>/<operation>, the same the web uses. A missing one is added inpackages/client(the add-feature skill), never a localfetchor a hand-written query key. - Route. A file in
apps/mobile/src/app/:(app)/<name>.tsxfor signed-in screens (a new tab also needs aTabs.Screeninapps/mobile/src/app/(app)/_layout.tsx),(auth)/<name>.tsxfor sign-in flows. Wrap content inScreen(src/components/screen.tsx), as(app)/settings.tsxdoes. - UI. Primitives from
src/components/ui/(Button, Card, Input, Text, …). A missing one: copy it from the React Native Reusables registry (https://reactnativereusables.com/r/uniwind/<name>.json; its CLI hangs without a terminal) and install what it lists withbunx expo installinapps/mobile. - Text.
useTranslations("<namespace>")fromuse-intl, keys in everypackages/i18n/messages/*.json, usually undermobile.*. They aren't type-checked here: confirm each key exists inen.json. Errors throughuseApiErrorMessage()from@repo/client, shared with web. - Native. A new permission, config plugin or native dependency changes
app.config.tsand needs a store build; say so in the pull request. - Tests. Logic in
src/libor a hook gets a Jest test beside it (bun run --filter @repo/mobile test). The screen gets a case inapps/mobile/e2e/app.spec.ts(Playwright on the web build). Anything only a device shows (permissions, OS links, restarts) gets a Maestro flow inapps/mobile/maestro/.
Done when
bun run lint,bun run --filter @repo/mobile check-typesandbun run --filter @repo/mobile testpass.bun run test:e2e --app mobilepasses (stopbun devfirst).- The
frontend-reviewerandi18n-checkeragents report nothing blocking.