Purl is a feature-rich, highly secure real-time messaging and calling application built with React Native and Expo. It provides an intuitive and native-feeling user experience with end-to-end encryption, high-quality audio/video calls, and seamless media sharing.
- Authentication: Multiple sign-in methods including Google Sign-In, Email/Password, and Phone number authentication.
- Real-time Messaging: Fast, real-time chat powered by Firebase Firestore.
- End-to-End Encryption (E2EE): Secure communication using advanced cryptographic algorithms (
tweetnacl, AES-GCM). - Voice & Video Calling: High-quality real-time communications integrated with Agora and
react-native-callkeepfor native call screens. - Media Sharing: Easily share photos and videos from your camera or gallery.
- Presence Tracking: Real-time online/offline status using Firebase Realtime Database.
- Push Notifications: Reliable notifications for messages and calls via FCM and Notifee.
- QR Code Invites: Generate and scan QR codes to quickly add contacts.
- Deep Linking: Native deep link support for sharing profiles and groups.
- Adaptive UI: Full support for both Light and Dark modes with smooth transitions.
- Framework: React Native & Expo (SDK 55)
- Navigation: Expo Router (File-based routing)
- State Management: Zustand
- Backend as a Service: Firebase (Auth, Firestore, Storage, Realtime DB, Functions)
- Communications: Agora RTC
- Encryption:
react-native-aes-gcm-crypto,tweetnacl
purl-app/
├── app/ # Expo Router pages and layouts
│ ├── (app)/ # Main authenticated app screens (Tabs: chats, calls, settings, status)
│ ├── (auth)/ # Authentication screens (welcome, email, phone, username)
│ ├── _layout.tsx # Root layout, Firebase initialization, theming
│ └── index.tsx # Entry point, routing logic based on auth state
├── src/ # Core application logic
│ ├── components/ # Reusable UI components
│ ├── hooks/ # Custom React hooks (e.g., usePresence)
│ ├── services/ # Integrations (Firebase, Agora, Notifee, Encryption, Deep Linking)
│ ├── store/ # Zustand global state (authStore)
│ ├── types/ # TypeScript type definitions
│ └── utils/ # Helper functions and constants
├── assets/ # Static assets (icons, splash screens)
├── functions/ # Firebase Cloud Functions
├── android/ # Native Android project files
└── ios/ # Native iOS project files
- Node.js:
v18or newer - Bun:
v1.0+(Used as the package manager, indicated bybun.lock) - Expo CLI: Installed globally or via
npx expo - React Native Environment: XCode for iOS development, Android Studio for Android.
- Firebase Project: A Firebase project with Auth, Firestore, Realtime DB, and Storage enabled.
- Agora Account: For voice and video calling features.
-
Clone the repository (if applicable) and navigate to the project directory:
cd purl-app -
Install dependencies:
bun install
-
Configure Firebase:
- Add your
GoogleService-Info.plistto the root directory for iOS. - Add your
google-services.jsonto the root directory for Android. - Ensure your Firebase project has the necessary services enabled and rules deployed (see
firestore.rules,storage.rules,database.rules.json).
- Add your
-
Environment Setup:
- Make sure you configure any required API keys for Agora or Google Sign-In within the project codebase (usually in
src/servicesor via environment variables).
- Make sure you configure any required API keys for Agora or Google Sign-In within the project codebase (usually in
-
Prebuild & Run: Because this app uses custom native code and modules (like WebRTC, Agora, Notifee, and Crypto), you need to run it via Expo Dev Client or build it natively.
To run on iOS:
bun run ios
To run on Android:
bun run android
This project uses EAS (Expo Application Services) for building.
-
Ensure you have the EAS CLI installed:
npm install -g eas-cli
-
Login to your Expo account:
eas login
-
Build the application:
eas build --platform ios eas build --platform android
This project is proprietary and confidential.