A React Native + Expo starter template for spinning up mobile prototype concepts fast. Keeps the design system, navigation shell, and component library; ships with empty screens and a scenario picker.
This is a template, not a prototype container. Don't build prototypes inside this repo — each prototype gets its own fork. Keep
scenarios.tsxempty onmainso the kit stays light.
Preferred — GitHub Template:
- Click "Use this template" → name it
proto-<concept>→ Create. gh repo clone itsHendri/proto-<concept> && cd proto-<concept>- Run the After cloning checklist below.
npm install && npx expo start(then pressifor the iOS Simulator).- Build variants in
src/prototype/, register them insrc/prototype/scenarios.tsx, ship vianpm run share.
Local-filesystem alternative:
cp -R swissborg-prototype-kit proto-<concept>
cd proto-<concept>
rm -rf .git node_modules dist
git init && npm install
# then follow the After cloning checklist belowChanges to the design system, shared components, or scenario system flow back into the kit. Changes to a specific prototype's variants stay in the prototype's fork.
Five-minute checklist for a freshly-forked prototype:
- Delete
.kit-template— its presence silences the setup-check warning. Once removed,npm startwill nag you about anything still set to the kit's defaults. package.json→ set"name"to your prototype's slug.app.json→ setexpo.name(shown under the icon) andexpo.slug.npx eas project:init(one-time) → writesexpo.extra.eas.projectIdandexpo.updates.urlback intoapp.json. Required beforenpm run sharecan publish.npm install && npx expo start, pressi. If Expo prompts "Install the recommended Expo Go version?" and the fetch fails, typen— the existing Expo Go on the Simulator is compatible.
- Navigation shell — 4-tab bottom bar (Home / Portfolio / Trade / Marketplace), floating glass header, Profile push, pushed Dev Kit screens.
- Industry-agnostic — a general mobile prototyping kit, not a crypto app.
Demos use neutral placeholders (
src/data/placeholders.ts); finance components ship as supported examples. - Design system — colour, typography, spacing, radius, elevation, and
motion tokens in
src/constants/, three-tier (primitives → semantic → components). SeeDESIGN_SYSTEM.md› "Design tokens & naming". - Light + dark themes —
darkColorsandlightColorspalettes with identical shape; every shared component reads through theuseThemeColors()hook insrc/context/ThemeContext.tsxso Profile → Theme flips the whole UI. Brand signal colors (accent, destructive, warning, info, badge) stay constant in both modes. - ~120 shared components organised under
src/components/shared/atoms/,…/molecules/,…/organisms/(Atomic Design on disk). Import through the barrel:import { Button, Card, TransactionRow } from '../components/shared'. Coverage spans the full modern mobile catalog across 8 functional areas — actions, inputs & selection, navigation, data display & charts, feedback & status, containers & layout, overlays & sheets, and media — plus cross-industry content patterns (profile/feed/chat/commerce/maps). Full registry inDESIGN_SYSTEM.md. - Scenario system — register prototype variants in
src/prototype/scenarios.tsx. A scenario is app-wide: pick one in Profile → Scenarios (single-select) and it takes over the whole screen — its own top bar, tabs, and chrome. A floating button returns to the picker. Also activatable via?scenario=<id>on web. Ships with one sample — a complete four-tab app (dashboard, holdings, trade flow, discovery) insrc/prototype/_samples/— so the picker isn't empty out of the box; it disappears the moment you register your own variant (delete the folder +sampleScenarios.tsxto remove for good). - Two dev surfaces under Profile — category-indexed accordion hubs
with global search (
src/screens/devkit/):- Components — functional categories; tap a category to expand its live previews in place.
- Styles — foundation categories (Color, Spacing & metrics, Typography, Iconography, Elevation, Motion), tap-to-copy.
- Scenarios index (web only,
/scenariosor Profile → Scenarios index) — flat list of every registered variant for stakeholder browsing without touching the Profile picker. - Web export to Figma — see
WEB_EXPORT.md. - Quality gates + CI —
npm run typecheckandnpm run lint(eslint-config-expo); GitHub Actions runs both on push/PR. - Claude Code agents & skills (
.claude/agents/,.claude/skills/) —/research(kit reuse map + Mobbin reference screens via MCP),/build-loop(autonomous build → QC → verify cycle),/qc-pass(audit report for any set of components),/changelog-update, plus thecomponent-builder/ui-qc-reviewer/kit-researchersubagents they delegate to. Forks inherit all of it. - CHANGELOG.md — dated milestone log of kit changes; keep
[Unreleased]current as you work.
npm install
npx expo start # canonical — pick the target interactivelynpm run typecheck # tsc --noEmit
npm run lint # expo lint (eslint-config-expo)npx expo start boots Metro and then waits for a single keystroke to
pick the target: i iOS Simulator, a Android, w web,
j debugger, r reload, m toggle dev menu. This is the
preferred entry point because the same Metro instance can serve every
target — no need to restart when you switch.
Expo Go on the iOS Simulator is the canonical preview surface —
that's i from the prompt. The web target (w) exists so screens can
be captured back into Figma (see WEB_EXPORT.md); it's not the intended
preview for design or stakeholder review.
The shortcut scripts (npm run ios, npm run web, npm run android)
still exist for muscle memory, but they're just expo start --<target>
under the hood and skip the interactive prompt.
If Expo prompts "Install the recommended Expo Go version?" and the
download fails with TypeError: fetch failed, type n (not Enter —
the default is yes). The Expo Go already on the Simulator is
compatible; only the auto-upgrade is failing.
-
Copy the template:
cp -R src/prototype/_template src/prototype/app, then renameScenarioTemplate.tsx→AppV1.tsxand rename the exported function to match. -
Edit
AppV1.tsx— the file already wires upShimmerGrid,PageTitleBar(hideBack, since a scenario is the app root), anAnimated.ScrollViewwith the right insets, and a sampleButton/Card. Replace the body. For a multi-tab prototype, render your ownBottomNavBar(seesrc/prototype/_samples/SampleApp.tsx). -
Register it in
src/prototype/scenarios.tsx:import { AppV1 } from './app/AppV1'; const prototypeScenarios: Scenario[] = [ { id: 'app-v1', label: 'App — V1', component: AppV1 }, ];
-
Open Profile → Scenarios in the running app and tap your variant — it takes over the whole app. (Registering it also hides the bundled sample.)
src/prototype/_template/ is a copy-this-file starter — never imported
into scenarios.tsx, so it stays invisible in the picker.
To share one variant directly, append ?scenario=home-v1 to the web
URL or — on web — open /scenarios (the stakeholder browse surface;
also reachable from Profile → Scenarios index on web).
npm run share -- "Short summary of the update"scripts/share.sh wraps eas update, parses the Update Group ID, and
prints the deep link in the canonical form:
exp://u.expo.dev/<projectId>/group/<updateGroupId>
Paste that into Slack / email and the recipient opens it directly in
Expo Go. The bare https://u.expo.dev/... URL 400s in a browser — Expo
Go expects the group/ form.
Prerequisites: eas whoami shows you're logged in, and
expo.extra.eas.projectId is present in app.json (one-time
npx eas project:init after cloning).
App.tsx providers, NavigationContainer, scenario URL bootstrap
src/
├── components/
│ ├── AppHeader.tsx avatar + title row above the tabs
│ ├── BottomTabBar.tsx
│ └── shared/ design-system component library
├── constants/ colour / spacing / typography / radius / elevation / motion tokens
├── context/ Theme (useThemeColors + useElevation), Toast, AppScroll, …
├── data/ mock seed + placeholders.ts (neutral demo content)
├── navigation/
│ ├── RootNavigator.tsx Main + Profile + Theme + Components + Styles
│ ├── TabNavigator.tsx Home / Portfolio / Trade / Marketplace
│ └── entries.ts
├── prototype/
│ ├── scenarios.tsx register variants here
│ └── _template/ copy-this-file starter (ignored by picker)
└── screens/
├── HomeScreen / PortfolioScreen / SwapScreen / MarketplaceScreen
│ default empty-shell tabs (scenarios take over app-wide)
├── TabScreen.tsx shared router shell + empty placeholder
├── MainLayout.tsx floating header + tab content
├── ProfileScreen.tsx Scenarios picker + dev surface links
├── ThemeScreen.tsx
├── devkit/ Components + Styles hubs (registry, categories,
│ sections/, foundations, DevKitHubScreen)
└── ScenariosIndexScreen.tsx web-only stakeholder browse
scripts/
├── check-setup.js prestart sanity check (slug, EAS projectId)
└── share.sh `npm run share -- "<msg>"` → Expo Go deep link