Introduction
Learn how to configure AIO
π¦ What AIO comes with:
- Authentication - Firebase Auth
- Analytics - Firebase Analytics
- Web Payments - Stripe
- In-App Purchases - RevenueCat
- Database - Firestore
- SEO - NextJS server-side rendering
- Internationalisation - i18n on all platforms
- Remote Push Notifications - Firebase Messaging
- Mobile Measurement Partner - AppsFlyer
- Expo (React Native + React Native Web)
- NextJS
- TypeScript
- Redux Toolkit
- NativeWind (cross-platform styling)
- Solito (cross-platform navigation)
- Moti / Reanimated (cross-platform animations)
- React-Native-Reusables (cross-platform shadcn-ui)
- Yarn Workspace Monorepo
π Folder layout
-
apps
entry points for each appexpo
app
you'll be creating files inside ofapps/expo/app
to use file system routing on iOS and Android.
next
app
(Next JS 14 App Directory) you'll be creating files inside ofapps/next/app/[locale]
to use locale-aware routing.
-
packages
shared packages across appsapp
you'll be importing most files fromapp/
assets
your app images, svgs, icons, animationsfeatures
your app's screens for expo and nextprovider
(all the providers that wrap the app, and some no-ops for Web.)hooks
(your app's custom hooks)interfaces
(your app's custom interfaces)design
your app's design system. organize this as you please.typography
(components for all the different text styles)layout
(components for layouts)
constants
your app's constants, envsstore
your app's redux storefirebase
your app's firebase config, and Auth Wrapperlib
utilities, hooks and constants for react native reusablescomponents
your app's custom componentsprimitives
contains react-native-reusables code for unstyled accessible components which uses radix-ui/primitives for the web.ui
contains react-native-reusables code for components styled with NativeWind. Most of these components are built using the primitives components.
utils
your app's custom utilities
π Libraries
- Next Intl for Localization
- NativeWind for Styling
- React Native Reusables for Components
- React Native Firebase for using Firebase Services in Expo App
- Lucide for Icons
- Redux Toolkit for state management
Pre-requisites
-
- Set up the following Firebase Services in your Firebase project:
- Authentication
- Enable Email/Password, Google and Apple Sign-in providers
- Functions
- Firestore
- Extensions
- Install the following Extensions:
- After installing the Extensions follow the extensions How this extension works guide to configure it.
- Configure the extensions to assign custom claims to your app users.
- Authentication
- Set up the following Firebase Services in your Firebase project:
-
- Integrate Firebase Extension in your RevenueCat Project
- Connect Your Stripe Account with RevenueCat
-
- Add a webhook in your Stripe project with the following events:
customer.subscription.created
checkout.session.completed
- The webhook url will be
https://<YOUR_WEBSITE_URL>/en/api/createCustomer
- Add a webhook in your Stripe project with the following events:
Setup
- Install dependencies:
yarn
- Replace Firebase, Stripe, Revenuecat API keys and envs in
packages/app/constants/envs.ts
- Replace expo configurations in
apps/expo/app.json
andapps/expo/eas.json
- AppsFlyer SDK: (Optional)
- To Add:
- Uncomment the code for appsflyer in
apps/expo/app/_layout.tsx
- Replace your appsflyer API keys & ID in
packages/app/constants/envs.ts
cd apps/expo
, Thennpx expo install react-native-appsflyer
- Add this config in plugins array in
apps/expo/app.json
["react-native-appsflyer", {}]
- Uncomment the code for appsflyer in
- To Add:
- Facebook SDK: (Optional)
- To Add:
- Install package:
yarn add react-native-fbsdk-next
- Uncomment the code for Facebook SDK in
apps/expo/app/_layout.tsx
- Uncomment the code for Facebook SDK in
apps/expo/app.json
and Replace with your keys
- Install package:
- To Add:
- Replace google-services.json and GoogleService-Info.plist in
apps/expo/google_services
- Localization:
- Translated text is in
packages/app/translations
- For using translated text in the app, import hook
useTranslation
frompackages/app/utils/useTranslations
- Add another language for localization
- Add the json file in
packages/app/translations
- Add the language code in
apps/next/i18n.ts
,apps/next/middleware.ts
,packages/app/store/slices/localeSlice.ts
,packages/app/utils/navigation/config.ts
,apps/expo/app/(root)/_layout.tsx
- Add the json file in
- Translated text is in
- Nativewind v4.
- For Expo it works fine.
- For Next JS it doesn't work by default. The solution for now is to add
/** @jsxImportSource react */
at the top of page.tsx or layout.tsx.- We will be updating the template when NativeWind has an improved solution for this.
- React Native Reusables
- Add a react native reusable component by following its documentation.
- For example, adding Button component run command
npx @react-native-reusables/cli@latest add button
inpackages/app
- Add Lucide icons in
packages/app/components/Icons.tsx
π Start the app
-
Install dependencies:
yarn
-
Next.js local dev:
cd apps/next
- Then run
yarn dev
OR - Run
yarn web
at the root of the monorepo
-
Expo local dev in:
- First, build a dev client onto your device or simulator
cd apps/expo
- Then, either
yarn android
, oryarn ios
- After building the dev client, Start Metro Server:
- Run
yarn start
OR
- Run
- Start from the root of the monorepo...
yarn native
(This runsexpo start --dev-client
)
- First, build a dev client onto your device or simulator
Pure JS dependencies
If you're installing a JavaScript-only dependency that will be used across platforms, install it in packages/app
:
Native dependencies
If you're installing a library with any native code, you must install it in apps/expo
:
π¦ Included packages
solito
for cross-platform navigationmoti
for animationsnativewind
for theming/design- Expo SDK 50
- Next.js 14
- Expo Router 3
- Expo:
- Permissions Included:
- AppTrackingTransparency
- Push Notification Permission
- Onboarding Flow Included:
packages/app/features/onboarding/screen.tsx
- Paywall Screen Included:
packages/app/features/subscription/screen.tsx
- Permissions Included:
SEO Metadata:
- Configure your metadata in
packages/app/constants/envs.ts
- Follow Vercel Docs for Optimizing your SEO metadata: https://nextjs.org/docs/app/building-your-application/optimizing/metadata
π Deployment
-
BUILD & SUBMIT iOS + ANDROID VERSION: (EAS)
cd apps/expo
eas build --auto-submit
-
DEPLOY WEB VERSION:
- Connect GitHub repo with Vercel
- Set root directory as βapps/nextβ in Vercel
- Push code to the branch connected with Vercel
-
BUILD iOS VERSION: (Locally)
cd apps/expo
eas build --platform ios --local
-
DEPLOY iOS VERSION: (Locally)
- Find the .ipa file in apps/expo generated via the local build command and upload to App Store Connect via the Transporter app.
-
BUILD ANDROID VERSION: (Locally)
cd apps/expo
eas build --platform android --local
-
DEPLOY ANDROID VERSION: (Locally)
- Find the generated .apk file and go to Google Play Developer Console to upload a new build for production
Subscription Logic for Template:
- We use RevenueCat as the single source of truth for cross-platform payment processing & subscription status checking.
-
Payment Logic:
- User makes purchase on Android/iOS -> We use RevenueCat to handle IAP -> We save subscription status in Firestore
- User makes purchase on Web -> We use Stripe to handle purchase -> We save subscription status in Firestore
- Subscription statuses are automatically updated via the RevenueCat & Stripe Firebase Extensions whenever they are cancelled/renewed/expired etc.
-
Check Subscription Status:
- User logs in on web -> We check for active subscription status in RevenueCat via their REST API.
- User logs in on mobile -> We check for active subscription status in RevenueCat via their SDK
Auth Logic:
- We use Firebase Auth, which makes auth super easy (itβs also completely free, unlike most auth services).
- By default, Apple & Google auth options are enabled. Be aware that Apple login is required if you release your app on iOS with authentication.
- If you wish to add more providers, it is very easy to do so.
-
Example Flow:
- User registers with Apple (βjohn@example.comβ) account
- User tries to login with his Google account (connected to the same email)
- Google is automatically added as an additional login option for the user.
π οΈ Local Development:
Install development build on iOS: (locally - requires Xcode installed)
cd apps/expo
eas build --profile development --platform ios --local
- Go to diawi.com -> Drag & drop your .ipa file -> Scan code with your phone
- Go back to root directory
(cd ../.. )
->yarn native
Install development build on Android: (locally - requires Android Studio installed)
cd apps/expo
eas build --profile development --platform android --local
- Install the generated .apk on your Phone or Emulator
- Go back to root directory
(cd ../.. )
->yarn native
Install development build on iOS: (EAS Cloud Build)
eas build --profile development --platform ios
- Go to expo.dev on your phone -> Find your generated .ipa build -> Tap on install
Install development build on Android: (EAS Cloud Build)
eas build --profile development --platform android
- Go to expo.dev on your phone -> Find your generated .apk build -> Tap on install
Note: You will only need to make a new development build if you make any changes to native libraries. When you make any other changes, your app simply updates in real-time with hot reloading. Read more: https://docs.expo.dev/develop/development-builds/introduction/
π Special Thanks
Fernando Rojo
Follow Fernando Rojo, creator of solito
, on Twitter: @FernandoTheRojo
We highly recommend watching Fernando's talk here, as well as reading the Solito docs.
Mark Lawlor
Follow Mark Lawlor, creator of NativeWind
, on Twitter: @mark__lawlor
Zach Nugent
Follow Zach Nugent, creator of react-native-reusables
, on Twitter: @mrzachnugent