Skip to main content
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:
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

EXPO_PUBLIC_API_BASE_URL
string
required
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
string
required
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
string
required
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:
.env.local
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

app.json
{
  "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
  }
}
name
string
Display name of the app
slug
string
URL-friendly identifier used for Expo services
version
string
App version number (semver format)
scheme
string
Deep linking URL scheme: dpmparceldeliveryapp://
userInterfaceStyle
string
Theme mode: "automatic", "light", or "dark"
newArchEnabled
boolean
Enable React Native’s new architecture (required for React 19)

iOS Configuration

app.json
{
  "expo": {
    "ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.felix-asante.dpm-parcel-delivery-app"
    }
  }
}
bundleIdentifier
string
Unique iOS bundle identifier (reverse domain notation)

Android Configuration

app.json
{
  "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"
    }
  }
}
package
string
Android package name (reverse domain notation)
edgeToEdgeEnabled
boolean
Enable edge-to-edge display (Android 15+)
permissions
array
Android permissions required by the app

Web Configuration

app.json
{
  "expo": {
    "web": {
      "output": "static",
      "favicon": "./src/assets/images/favicon.png"
    }
  }
}
output
string
Build output type. "static" generates static HTML/JS/CSS for hosting.

Expo Plugins

Plugins extend app functionality with native capabilities:
app.json
{
  "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

app.json
{
  "expo": {
    "experiments": {
      "typedRoutes": true,
      "reactCompiler": true
    }
  }
}
typedRoutes
boolean
Generate TypeScript types for Expo Router routes
reactCompiler
boolean
Enable React 19 compiler optimizations

Application Constants

Currency Configuration

The app’s currency settings are defined in src/constants/config.ts:
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:
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

tsconfig.json
{
  "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:
metro.config.js
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

Build docs developers (and LLMs) love