- Framework: React Native
- Language: TypeScript
- State Management: React Native Onyx
- Navigation: React Navigation
- Platforms: iOS, Android, Web, Desktop (Electron)
IMPORTANT: The mobile application is built from the Mobile-Expensify submodule, not directly from the App repository. IMPORTANT: NewDot refers to the new Expensify App, OldDot or Expensify Classic refers to our Old expensify app and website
- App (NewDot) and Mobile-Expensify (OldDot) are combined into a single mobile application
- The HybridApp module (
@expensify/react-native-hybrid-app) manages transitions between OldDot and NewDot - Build process merges dotenv configurations from both repositories
- Environment variables from Mobile-Expensify take precedence over App variables
- Mobile builds must be initiated from the Mobile-Expensify directory
- Standalone: Pure NewDot application (web/desktop)
- HybridApp: Combined OldDot + NewDot (mobile apps)
- Controlled via
STANDALONE_NEW_DOTenvironment variable
src/App.tsx: Main application component with provider hierarchysrc/Expensify.tsx: Core application logic and initializationsrc/HybridAppHandler.tsx: Manages HybridApp transitions and authenticationindex.js: React Native entry point
The application uses a nested provider structure for context management:
- SplashScreenStateContextProvider: Manages splash screen visibility
- InitialURLContextProvider: Handles deep linking
- ThemeProvider: Theme management
- LocaleContextProvider: Internationalization
- OnyxListItemProvider: Data layer provider
- SafeAreaProvider: Device safe areas
- PopoverContextProvider: Global popover state
- KeyboardProvider: Keyboard state management
- Onyx: Custom data persistence layer for offline-first functionality
- ONYXKEYS.ts: Centralized key definitions for data store
- Supports optimistic updates and conflict resolution
-
Expense Management
- Receipt scanning and SmartScan
- Expense creation and editing
- Distance tracking
- Per diem support
- Split expenses
-
Reporting
- Report creation and submission
- Approval workflows
- Report fields and custom attributes
- Bulk operations
-
Workspace/Policy Management
- Policy creation and configuration
- Member management
- Categories, tags, and tax rates
- Accounting integration settings
- Approval workflows
-
Travel
- Trip management
- Travel booking integration
- Travel policy enforcement
-
Search & Filtering
- Advanced search with filters
- Saved searches
- Search parser (Peggy-based)
-
Payment & Cards
- Expensify Card management
- Bank account connections (Plaid)
- Payment methods
- Company cards integration
- Wallet functionality
-
Accounting Integrations
- QuickBooks Online
- Xero
- NetSuite
- Sage Intacct
- QuickBooks Desktop
- Generic accounting connections
-
Communication
- Chat functionality
- Task management
- Mentions and notifications
- Thread organization
-
Invoice Management
- Invoice creation and sending
- Invoice rooms
src/SCREENS.ts: Screen name constantssrc/ROUTES.ts: Route definitions and builderssrc/NAVIGATORS.ts: Navigator configuration
- ProtectedScreens: Authenticated app screens
- PublicScreens: Login and onboarding screens
- RHP (Right Hand Panel/Pane): Settings and details panel
- Central Pane: Main content area
- LHN (Left Hand Navigation): Report list and navigation
- RHP: Contextual panels and settings
- Session: Authentication and user session
- Personal Details: User profiles and preferences
- Reports: Chat and expense reports
- Transactions: Expense transactions
- Policy: Workspace configuration
- Forms: Form state management
Major action categories:
App.ts: Application lifecycleIOU.ts: Money requests and expensesReport.ts: Report managementPolicy/: Workspace operationsUser.ts: User account operationsSession.ts: AuthenticationSearch.ts: Search operationsTravel.ts: Travel features
Key GitHub Actions workflows:
deploy.yml: Production deploymentpreDeploy.yml: Staging deploymenttestBuild.yml: PR test buildstest.yml: Unit teststypecheck.yml: TypeScript validationlint.yml: Code quality checkse2ePerformanceTests.yml: Performance testing
- Path:
App/Mobile-Expensify/ - Purpose: Legacy OldDot application and mobile build source
- Critical: All mobile builds originate from this directory
- Contains platform-specific code for iOS and Android
- Manages the HybridApp integration layer
- Purpose: Shared libraries and utilities
- Contains common validation, parsing, and utility functions
- Used across multiple Expensify repositories
- TypeScript: Strict mode enabled
- ESLint: Linter
- Prettier: Automatic formatting
- Patch Management: patch-package for dependency fixes
- Unit Tests: Jest with React Native Testing Library
- E2E Tests: Custom test runner
- Performance Tests: Reassure framework
- All features work offline
- Optimistic updates with rollback
- Queue-based request handling
- Conflict resolution strategies
- Push notifications via Airship
- Mapbox integration for location features
- Camera and gallery access
- Content Security Policy enforcement
- Two-factor authentication support
- NewDot Help: https://help.expensify.com/new-expensify/hubs/
- OldDot/Expensify Classic Help: https://help.expensify.com/expensify-classic/hubs/
# Install dependencies
npm install
# Clean build artifacts
npm run clean
# Type checking
npm run typecheck
# Linting
npm run lint
# Testing
npm run test# iOS build
npm run ios
# Android build
npm run android
# Desktop build
npm run desktop
# Web build
npm run web- Fabric renderer enabled
- TurboModules for native module integration
- Hermes JavaScript engine
- Custom Onyx library for offline-first capabilities
- Optimistic updates as default pattern
- Centralized action layer for API calls
- Direct key-value storage with automatic persistence
- React Navigation for cross-platform consistency
- Custom navigation state management
- Deep linking support
- Session sharing via HybridApp module
- Navigation handoff between apps
- Shared authentication state
- Environment variable merging
- RESTful API communication
- WebSocket connections via Pusher
- Real-time synchronization