This guide covers all configuration aspects of the DPM Delivery Mobile app, including environment variables, app.json settings, and application constants.
Environment Variables
Environment variables are defined in .env.local and accessed via process.env with the EXPO_PUBLIC_ prefix.
Required Variables
All environment variables are validated at runtime in src/utils/env.ts:
function validateEnv(env: string | undefined) {
if (!env) {
throw new Error(`Environment variable ${env} is not defined`);
}
return env.trim();
}
export const ENV = {
encryptionKey: validateEnv(process.env.EXPO_PUBLIC_ENCRYPTION_KEY),
apiBaseUrl: validateEnv(process.env.EXPO_PUBLIC_API_BASE_URL),
webCryptoKey: validateEnv(process.env.EXPO_PUBLIC_WEB_CRYPTO_KEY),
};
Variable Definitions
Backend API base URL. Used by all API services to construct endpoints.Example: https://api.dpm-delivery.comUsage: Referenced in src/services/api/end-points.ts
EXPO_PUBLIC_ENCRYPTION_KEY
Encryption key for MMKV storage on native platforms. Used to encrypt sensitive data stored locally.Format: 32-character alphanumeric stringUsage: Used in src/utils/storage.ts for MMKV initialization
EXPO_PUBLIC_WEB_CRYPTO_KEY
Encryption key for Web Crypto API on web platform. Used for browser-based encrypted storage.Format: 32-character alphanumeric stringUsage: Used in src/utils/web-crypto.ts for web encryption
Setting Up Environment Variables
Create a .env.local file in the project root:
EXPO_PUBLIC_API_BASE_URL=https://your-api.example.com
EXPO_PUBLIC_ENCRYPTION_KEY=your-32-char-encryption-key-here
EXPO_PUBLIC_WEB_CRYPTO_KEY=your-32-char-web-crypto-key-here
Never commit .env.local to version control. Ensure it’s listed in .gitignore.
Different Environments
For multiple environments (development, staging, production), use separate env files:
# Development
.env.local
# Staging
.env.staging
# Production
.env.production
Load specific environment:
# Use staging environment
cp .env.staging .env.local
bun start
App Configuration (app.json)
The app.json file contains Expo-specific configuration for the app.
Basic Configuration
{
"expo": {
"name": "dpm-parcel-delivery-app",
"slug": "dpm-parcel-delivery-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./src/assets/images/icon.png",
"scheme": "dpmparceldeliveryapp",
"userInterfaceStyle": "automatic",
"newArchEnabled": true
}
}
URL-friendly identifier used for Expo services
App version number (semver format)
Deep linking URL scheme: dpmparceldeliveryapp://
Theme mode: "automatic", "light", or "dark"
Enable React Native’s new architecture (required for React 19)
iOS Configuration
{
"expo": {
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.felix-asante.dpm-parcel-delivery-app"
}
}
}
Unique iOS bundle identifier (reverse domain notation)
Android Configuration
{
"expo": {
"android": {
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./src/assets/images/android-icon-foreground.png",
"backgroundImage": "./src/assets/images/android-icon-background.png",
"monochromeImage": "./src/assets/images/android-icon-monochrome.png"
},
"edgeToEdgeEnabled": true,
"predictiveBackGestureEnabled": false,
"permissions": [
"android.permission.RECORD_AUDIO"
],
"package": "com.felixasante.dpmparceldeliveryapp"
}
}
}
Android package name (reverse domain notation)
Enable edge-to-edge display (Android 15+)
Android permissions required by the app
Web Configuration
{
"expo": {
"web": {
"output": "static",
"favicon": "./src/assets/images/favicon.png"
}
}
}
Build output type. "static" generates static HTML/JS/CSS for hosting.
Expo Plugins
Plugins extend app functionality with native capabilities:
{
"expo": {
"plugins": [
"expo-router",
[
"expo-splash-screen",
{
"image": "./src/assets/images/splash-icon.png",
"imageWidth": 200,
"resizeMode": "contain",
"backgroundColor": "#f15925",
"dark": {
"backgroundColor": "#f15925"
}
}
],
[
"expo-image-picker",
{
"photosPermission": "The app accesses your photos to let you share them.",
"cameraPermission": "The app accesses your camera to let you take photos."
}
]
]
}
}
expo-router
Enables file-based routing for the app.
expo-splash-screen
Configures the splash screen shown during app launch.
expo-image-picker
Enables photo selection and camera access with permission messages.
Experimental Features
{
"expo": {
"experiments": {
"typedRoutes": true,
"reactCompiler": true
}
}
}
Generate TypeScript types for Expo Router routes
Enable React 19 compiler optimizations
Application Constants
Currency Configuration
The app’s currency settings are defined in src/constants/config.ts:
export const AppConfig = {
currency: {
label: "Cedis",
symbol: "₵",
},
};
Usage:
import { AppConfig } from "@/constants/config";
// Display currency symbol
const formattedPrice = `${AppConfig.currency.symbol}${amount}`;
Changing Currency:
To use a different currency, update the config.ts file:
export const AppConfig = {
currency: {
label: "Dollars",
symbol: "$",
},
};
Theme Constants
Theme colors and fonts are defined in src/constants/theme.ts:
import { Platform } from 'react-native';
const tintColorLight = '#0a7ea4';
const tintColorDark = '#fff';
export const Colors = {
light: {
text: '#11181C',
background: '#fff',
tint: tintColorLight,
icon: '#687076',
tabIconDefault: '#687076',
tabIconSelected: tintColorLight,
},
dark: {
text: '#ECEDEE',
background: '#151718',
tint: tintColorDark,
icon: '#9BA1A6',
tabIconDefault: '#9BA1A6',
tabIconSelected: tintColorDark,
},
};
export const Fonts = Platform.select({
ios: {
sans: 'system-ui',
serif: 'ui-serif',
rounded: 'ui-rounded',
mono: 'ui-monospace',
},
default: {
sans: 'normal',
serif: 'serif',
rounded: 'normal',
mono: 'monospace',
},
web: {
sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto",
// ... other font families
},
});
See Styling for more details on theme usage.
Build Configuration
TypeScript Configuration
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
The @/ path alias allows importing from src/:
import { ENV } from "@/utils/env";
import { AppConfig } from "@/constants/config";
Metro Configuration
Metro bundler is configured in metro.config.js with Uniwind integration:
const { getDefaultConfig } = require("expo/metro-config");
const { withUniwindConfig } = require("uniwind/metro");
const config = getDefaultConfig(__dirname);
module.exports = withUniwindConfig(config, {
cssEntryFile: "./src/global.css",
dtsFile: "./src/uniwind-types.d.ts",
});
This enables:
- Tailwind CSS processing
- Auto-generated TypeScript types for themes
- CSS-in-JS transformation
Next Steps