A React Native mobile app for Backpocket, built with Expo SDK 54.
- 📱 Native look & feel with Backpocket's brand theme
- 🔐 Clerk authentication with SecureStore token persistence
- 🔗 Share to Backpocket - Share URLs from any app to save automatically
- 📚 Full save management - Create, view, favorite, archive, delete saves
- 📁 Collections & Tags - Organize your saves
- 🌗 Light/Dark mode - Follows system preference
- 🎨 NativeWind - Tailwind CSS styling for React Native
- Framework: Expo SDK 54 + Expo Router
- Auth: Clerk Expo + SecureStore
- API: tRPC (HTTP fetch with Bearer tokens)
- State: TanStack Query (React Query)
- Styling: NativeWind (Tailwind CSS)
- Icons: Lucide React Native
- Fonts: DM Sans + Fraunces (Google Fonts)
- Node.js 18+ or Bun
- iOS Simulator (Mac) or Android Emulator
- Expo Go app (for quick testing) or EAS Build (for share extension)
- Install dependencies:
bun install- Create
.env.localfrom the example:
cp .env.example .env.local- Add your Clerk publishable key and API URL to
.env.local:
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
EXPO_PUBLIC_API_URL=https://backpocket.devStart the development server:
bun startRun on iOS:
bun iosRun on Android:
bun androidThe iOS share extension requires a development build (not Expo Go).
npx eas build --profile development --platform ios- User shares a URL from any app (Safari, Twitter, etc.)
- iOS share sheet shows "Backpocket" option
- Minimal share extension UI extracts the URL
- Opens the host app via
backpocket://share?url=... - Host app auto-saves the URL via API
- User sees success confirmation
Share intent works via the expo-share-intent plugin. When a user shares text/URL to Backpocket:
- Android sends the intent to the app
- App opens to
/shareroute with the shared data - Auto-save flow proceeds same as iOS
backpocket-mobile/
├── app/ # Expo Router screens
│ ├── (auth)/ # Auth screens (sign-in, sign-up)
│ ├── (tabs)/ # Main tab navigator
│ │ ├── index.tsx # Dashboard
│ │ ├── saves.tsx # Saves list
│ │ ├── collections.tsx
│ │ ├── tags.tsx
│ │ └── settings.tsx
│ ├── save/ # Save detail screens
│ │ ├── [id].tsx # Save detail
│ │ └── new.tsx # Add new save
│ ├── share.tsx # Share handler route
│ └── _layout.tsx # Root layout
├── components/
│ ├── ui/ # UI primitives
│ └── providers.tsx # App providers
├── lib/
│ ├── api/ # tRPC client & hooks
│ ├── auth/ # Clerk token cache
│ ├── theme/ # Theme tokens & provider
│ └── constants.ts # App configuration
├── constants/
│ └── theme.ts # Colors, fonts, shadows
├── hooks/ # Custom hooks
├── ShareExtension.tsx # iOS share extension UI
├── index.js # Host app entry
└── index.share.js # Share extension entry
app.json- Expo config with pluginseas.json- EAS Build configurationmetro.config.js- Metro bundler + NativeWind + Share Extensiontailwind.config.js- NativeWind/Tailwind themebabel.config.js- Babel + NativeWind preset
The app communicates with the Next.js web app's tRPC API:
- Base URL:
EXPO_PUBLIC_API_URL(default:https://backpocket.dev) - Auth: Clerk JWT tokens via
Authorization: Bearer <token>header - Endpoints: Same as web (
space.createSave,space.listSaves, etc.)
npx eas build --profile production --platform ios
npx eas submit --platform iosnpx eas build --profile production --platform android
npx eas submit --platform android| Variable | Description | Required |
|---|---|---|
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY |
Clerk publishable key | Yes |
EXPO_PUBLIC_API_URL |
Backend API URL | Yes (default: https://backpocket.dev) |
Private - Backpocket