Complete setup, build, and customization guide. v1.0.0
npm install -g expo-clinpm install -g eas-cli# 1. Navigate to the mobile folder
cd mobile
# 2. Install dependencies
npm install
# 3. Copy the example environment file
cp .env.example .env
# 4. Open .env and add your OpenAI API key (see section 2)
# 5. Start the development server
npx expo start
# 6. Scan the QR code with Expo Go on your phone
The mobile app uses a single .env file in the mobile/ folder.
| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
Yes | Your OpenAI API key for the Lily AI chat feature. Get one at platform.openai.com/api-keys. The app uses the gpt-4o model. Without this key, the AI chat will show an error message but the rest of the app works fine. |
sk-)mobile/.env as: OPENAI_API_KEY=sk-your-key-hereThe key is read via expo-constants from app.json > expo.extra.openaiApiKey. The babel.config.js uses dotenv to inject it at build time. If you prefer, you can hardcode it directly in app.json under:
{
"expo": {
"extra": {
"openaiApiKey": "sk-your-key-here"
}
}
}
# Install EAS CLI globally
npm install -g eas-cli
# Log in to your Expo account
eas login
# Configure the project (only needed once)
eas build:configure
cd mobile
eas build --platform android --profile preview
This creates a .apk file you can share and install directly on Android devices.
cd mobile
eas build --platform android --profile production
This creates an .aab (Android App Bundle) for uploading to the Google Play Console.
cd mobile
eas build --platform ios --profile production
Requires an Apple Developer account ($99/year). EAS handles code signing automatically.
# Submit to Google Play (requires service account key)
eas submit --platform android --profile production
# Submit to App Store
eas submit --platform ios --profile production
Before each release, update these in mobile/app.json:
| Field | Location | Description |
|---|---|---|
version | expo.version | User-facing version (e.g., "1.2.0") |
versionCode | expo.android.versionCode | Android build number (integer, must increment every upload) |
versionCode is not higher than the previous upload. Always increment it.The core feature. Users log their period start date, cycle length, and period length during onboarding. The app then calculates:
Flow logging feeds back into predictions — when users log their actual flow, the app detects real period length and recalculates averages for future predictions.
Lily is an AI health companion powered by GPT-4o. She has gynecological-level knowledge and personalizes every response based on the user's current cycle phase, mood, symptoms, and pregnancy status.
Advanced fertility tracking with:
When enabled, the app switches to pregnancy tracking:
Three tabs: Health Insights (AI-detected patterns, predictions, health score), Mood Tracker (mood logging with trend analysis), and Resource Library (curated health articles with external links).
/invite.html?code=XXXAll local (no server needed):
Supports English and Hindi. Language selection during onboarding. Users can change language anytime in Profile settings.
Context-aware tips on the home screen based on cycle phase, mood, time of day, fertile window status, and pregnancy trimester. Covers nutrition, exercise, wellness, sleep, and self-care.
mobile/src/locales/ (e.g., es.json for Spanish)en.json and translate all valuesmobile/src/lib/i18n.ts:
import es from '../locales/es.json';
export const SUPPORTED_LANGUAGES = ['en', 'hi', 'es'] as const;
export const LANGUAGE_LABELS = {
en: 'English',
hi: 'हिन्दी',
es: 'Español',
};
// In initI18n(), add to resources:
resources: {
en: { translation: en },
hi: { translation: hi },
es: { translation: es },
},
WelcomeScreen.tsx in the LANGUAGES arrayAll colors are defined in mobile/src/lib/theme.ts. The app uses a pink/purple gradient theme. To change:
// mobile/src/lib/theme.ts
export const colors = {
pink: { 50: '#fdf2f8', 500: '#ec4899', 600: '#db2777', ... },
purple: { 50: '#faf5ff', 500: '#a855f7', 600: '#9333ea', ... },
// Change these to your brand colors
};
The gradient used throughout the app is defined in:
export const gradients = {
bloom: [colors.pink[500], colors.purple[600]],
};
Open mobile/src/lib/aiService.ts:
const MODEL = 'gpt-4o'; // Change to 'gpt-4o-mini' for cheaper, less accurate
const API_URL = 'https://api.openai.com/v1/chat/completions';
To use a different AI provider (Claude, Gemini, etc.), modify the sendChatMessage() function to match their API format.
Open mobile/src/lib/referralService.ts:
export function getChatMessageLimit(referralCount: number): number {
if (referralCount >= 25) return -1; // unlimited
if (referralCount >= 5) return 15;
return 5; // base limit — change this number
}
Edit mobile/app.json:
{
"expo": {
"name": "Your App Name",
"slug": "your-app-slug",
"ios": { "bundleIdentifier": "com.yourcompany.yourapp" },
"android": { "package": "com.yourcompany.yourapp" }
}
}
Replace these files in mobile/assets/:
icon.png — 1024x1024px, app iconadaptive-icon.png — 1024x1024px, Android adaptive icon foregroundsplash.png — 1284x2778px, splash screen imagefavicon.png — 48x48px, web faviconThe app checks https://bloom.metanetica.in/version.json every 6 hours. Update this file when you publish a new version:
{
"android": "1.2.0",
"ios": "1.2.0",
"forceUpdate": false,
"releaseNotes": "New features and bug fixes."
}
Set forceUpdate: true for critical updates — the user cannot dismiss the update popup.
To change the URL, edit mobile/src/lib/updateChecker.ts:
const VERSION_CHECK_URL = 'https://your-domain.com/version.json';
mobile/
├── App.tsx # Entry point, providers, deep linking
├── app.json # Expo config (name, version, permissions, plugins)
├── eas.json # EAS Build profiles
├── .env # Environment variables (API keys)
├── assets/ # Icons, splash screen, images
├── src/
│ ├── components/ # Reusable UI components
│ │ ├── CycleRing.tsx # Cycle visualization ring
│ │ ├── StreakWidget.tsx # Gamification streak card
│ │ ├── DailyTipsCard.tsx # Personalized daily tips
│ │ ├── DailyLogPrompt.tsx # Mood/flow logging popup
│ │ ├── QuickLogModal.tsx # Quick log bottom sheet
│ │ ├── FormattedText.tsx # Markdown renderer for AI chat
│ │ ├── UpdateBanner.tsx # App update popup
│ │ └── ...
│ ├── context/ # React Context providers
│ │ ├── AuthContext.tsx # Authentication state
│ │ ├── CycleContext.tsx # Cycle data, predictions, flow feedback
│ │ ├── NotificationContext.tsx # Push notifications
│ │ ├── AppLockContext.tsx # Biometric lock
│ │ └── LanguageContext.tsx # i18n language state
│ ├── lib/ # Business logic & services
│ │ ├── aiService.ts # OpenAI GPT-4o integration
│ │ ├── cycleLogic.ts # Cycle phase calculations
│ │ ├── gamificationService.ts # Streaks, badges, points
│ │ ├── referralService.ts # Referral codes & chat limits
│ │ ├── notificationService.ts # Cycle/pregnancy notifications
│ │ ├── pushNotificationService.ts # Expo push scheduling
│ │ ├── predictionConfidence.ts # Prediction accuracy scoring
│ │ ├── personalizedTips.ts # Daily tip generation
│ │ ├── probabilityEngine.ts # Conception probability
│ │ ├── fertileWindowPredictor.ts # Fertile window calc
│ │ ├── ovulationDetector.ts # BBT thermal shift detection
│ │ ├── storage.ts # AsyncStorage data layer
│ │ ├── theme.ts # Colors and gradients
│ │ ├── i18n.ts # Internationalization setup
│ │ ├── navigationRef.ts # Global navigation ref
│ │ └── updateChecker.ts # App version checker
│ ├── locales/ # Translation files
│ │ ├── en.json # English
│ │ └── hi.json # Hindi
│ ├── navigation/ # Navigation setup
│ │ ├── RootNavigator.tsx # Onboarding flow + stack navigator
│ │ └── MainTabs.tsx # Bottom tab navigator
│ └── screens/ # App screens
│ ├── HomeScreen.tsx # Main dashboard
│ ├── CalendarScreen.tsx # Cycle calendar
│ ├── AIChatScreen.tsx # Lily AI chat
│ ├── InsightsScreen.tsx # Health insights + mood tracker
│ ├── ProfileScreen.tsx # Settings & profile
│ ├── AchievementsScreen.tsx # Badges & streaks
│ ├── ReferralScreen.tsx # Invite friends
│ ├── PregnancyPlanningScreen.tsx # Fertility tracking
│ ├── WelcomeScreen.tsx # Onboarding carousel
│ └── ...
└── website/ # Landing page & docs
├── index.html # Main landing page
├── invite.html # Referral invite page
├── version.json # App version for update checker
└── documentation.html # This file
Bloom follows Semantic Versioning (MAJOR.MINOR.PATCH):
| Segment | When to bump | Example |
|---|---|---|
MAJOR | Breaking changes — data migration required, removed features, or incompatible API changes | 1.x.x → 2.0.0 |
MINOR | New features that are backward-compatible | 1.2.x → 1.3.0 |
PATCH | Bug fixes, performance improvements, minor UI tweaks | 1.2.0 → 1.2.1 |
| File | Field | Purpose |
|---|---|---|
mobile/app.json | expo.version | User-facing version string shown in the app and stores |
mobile/app.json | expo.android.versionCode | Android build number (integer, must increment every Play Store upload) |
mobile/app.json | expo.ios.buildNumber | iOS build number (string, must increment every App Store upload) |
mobile/package.json | version | npm package version — keep in sync with app.json |
website/version.json | android / ios | Used by the in-app update checker to prompt users |
expo.version in mobile/app.jsonexpo.android.versionCode (and expo.ios.buildNumber if applicable)version in mobile/package.json to matcheas build and test the production buildeas submitwebsite/version.json so existing users see the update prompt"forceUpdate": true in version.json only for critical security or data-integrity fixes. Users cannot dismiss a forced update banner.v1.0.0 — Initial CodeCanyon release (April 2026). See the full release history on the Changelog page.
| Library | License | Purpose |
|---|---|---|
| React Native | MIT | Cross-platform mobile framework |
| Expo (SDK 54) | MIT | Development platform and build tools |
| React Navigation 7 | MIT | Screen navigation (stack + tabs) |
| TypeScript | Apache-2.0 | Type-safe JavaScript |
| Library | License | Purpose |
|---|---|---|
| @expo/vector-icons (Ionicons) | MIT | Icon set |
| expo-blur | MIT | iOS frosted glass tab bar |
| expo-linear-gradient | MIT | Gradient backgrounds and buttons |
| react-native-safe-area-context | MIT | Safe area insets |
| @react-native-community/datetimepicker | MIT | Date picker for period/pregnancy dates |
| Library | License | Purpose |
|---|---|---|
| @react-native-async-storage/async-storage | MIT | Local data persistence |
| expo-secure-store | MIT | Encrypted storage for sensitive data |
| expo-file-system | MIT | File operations |
| Library | License | Purpose |
|---|---|---|
| expo-notifications | MIT | Local push notifications |
| expo-local-authentication | MIT | Biometric lock (Face ID / fingerprint) |
| expo-localization | MIT | Device locale detection |
| i18next + react-i18next | MIT | Internationalization |
| date-fns | MIT | Date calculations |
| expo-clipboard | MIT | Copy referral code |
| Service | Type | Purpose |
|---|---|---|
| OpenAI GPT-4o | Paid API | Lily AI chat — gynecological health companion |
All libraries are MIT or Apache-2.0 licensed. No proprietary dependencies.
| Channel | Contact |
|---|---|
| support@metanetica.in | |
| Website | bloom.metanetica.in |
| Bug Reports | support@metanetica.in |
© 2026 Metanetica. All rights reserved. Bloom is not a medical device. Read disclaimer.