Skip to main content
Shipnative’s service architecture is designed to be modular. Adding a new service follows a consistent pattern across the codebase.

Architecture Overview

Services implement platform-agnostic interfaces, making it easy to swap providers or add new ones:
Key principles:
  • Each service implements a TypeScript interface
  • Platform detection handles iOS/Android/Web differences automatically
  • Services fail gracefully when credentials are missing
  • Feature flags control service availability

Adding a New Service

Let’s walk through adding a hypothetical service. The same pattern applies whether you’re adding OneSignal, Firebase, Convex, Amplitude, or any other provider.

Step 1: Define the Interface

Create a type definition in apps/app/app/types/:
Export from the types index:

Step 2: Add Environment Variables

Update the Zod schema in apps/app/app/config/env.ts:
Add to the isServiceConfigured function:

Step 3: Add Feature Flag

Update apps/app/app/config/features.ts:

Step 4: Create the Service

Create the service implementation in apps/app/app/services/:

Step 5: Initialize in App

Add initialization to apps/app/app/app.tsx:

Step 6: Use the Service


Quick Reference: Files to Update


Common Integrations

Push Notifications (OneSignal)

Replace or extend the existing Expo notifications:

Realtime Database (Convex)

Add alongside or instead of Supabase realtime:

Analytics (Amplitude, Mixpanel)

The existing AnalyticsService interface works for most providers:

Replacing Existing Services

To swap out a service (e.g., PostHog → Amplitude):
  1. Create new implementation using the same interface
  2. Update the export in the service file
  3. No other code changes needed

Platform-Specific SDKs

Many services have different SDKs for mobile and web:

Testing Your Integration

  1. Without credentials: Service should skip initialization gracefully
  2. With credentials: Verify initialization logs appear
  3. Cross-platform: Test on iOS, Android, and Web
Check the console for initialization logs:

Troubleshooting

Service not initializing?
  • Verify environment variable is set in apps/app/.env
  • Check variable is prefixed with EXPO_PUBLIC_
  • Restart Metro: yarn app:start --clear
TypeScript errors?
  • Ensure interface is exported from types/index.ts
  • Check import paths use @/ alias
Platform-specific issues?
  • Verify SDK is installed: yarn add service-react-native
  • Check SDK supports your React Native version
  • Review SDK documentation for Expo compatibility