Skip to main content

Step 1: Create the React Native app

What we are building​

An Expo Router app that compiles for iOS and Android and has the native modules needed for Ovok authentication, local notifications, and encrypted offline storage.

What you should already have​

  • Node.js and a package manager.
  • Xcode for iOS builds and/or Android Studio for Android builds.
  • Access to a development device or simulator.

The implementation​

Create an Expo tabs app and install the Ovok packages. The minimum versions validated for this tutorial are @ovok/core 0.4.27 and @ovok/native 1.10.6; use the Native SDK installation guide for platform compatibility requirements.

npx create-expo-app@latest ovok-medication-reminder --template tabs
cd ovok-medication-reminder
npm install @ovok/core@^0.4.27 @ovok/native@^1.10.6 formik yup i18next react-i18next
npm install iconsax-react-nativejs
npx expo install @expo-google-fonts/dm-sans @gorhom/bottom-sheet react-native-ble-plx react-native-permissions react-native-reanimated expo-notifications expo-sqlite expo-secure-store expo-crypto expo-standard-web-crypto expo-dev-client expo-constants @react-native-community/netinfo react-native-safe-area-context react-native-gesture-handler react-native-keyboard-controller react-native-paper react-native-svg

Keep the Expo SDK version compatible with the Native SDK installation guide. npx expo install selects the native package versions for that Expo SDK.

Check the Native SDK guide's current iOS deployment target and Android minimum SDK before building; those values follow the supported SDK baseline and can change. This tutorial does not use Bluetooth, HealthKit, or Health Connect, so do not add those permissions or plugins.

Run Ovok's web platform polyfills first​

Create index.js in the project root and make it the app entry in package.json:

const { polyfillOvokWebAPIs } = require("@ovok/native/polyfills");

polyfillOvokWebAPIs();
require("expo-router/entry");
{
"main": "index.js"
}

The polyfills must run before the client or screens import Ovok.

Configure native plugins​

Add the notification, secure storage, and SQLCipher plugins to app.config.ts. Keep the bundle identifiers generated for your application:

import type { ExpoConfig } from "expo/config";

const config: ExpoConfig = {
name: "Ovok Medication Reminder",
slug: "ovok-medication-reminder",
plugins: [
"expo-router",
"expo-notifications",
"expo-secure-store",
["expo-sqlite", { useSQLCipher: true }],
],
ios: { bundleIdentifier: "com.example.ovokmedication" },
android: { package: "com.example.ovokmedication" },
};

export default config;

On iOS, local notifications require the patient's permission; step 7 requests it at the point the app explains reminders. On Android, create the notification channel before requesting runtime permission, also covered in step 7. The tutorial does not configure push credentials, background remote notifications, or exact-alarm permissions. Let the operating system control delivery timing. A notification is a reminder, not a clinical alert.

Add public sandbox configuration​

Create .env.example, copy it to .env.local, and keep that local file out of version control:

EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com
EXPO_PUBLIC_TENANT_CODE=replace-with-your-sandbox-tenant-code

Expo embeds EXPO_PUBLIC_ values in the application bundle. Store only public environment configuration here—never passwords, access tokens, or server credentials.

Build a development app​

SQLCipher is configured at build time and is not available in Expo Go. Create a development build after adding the plugins:

npx expo prebuild
npx expo run:ios
# or
npx expo run:android

Local notifications can be previewed in Expo Go, but the encrypted database configuration requires your own native development build. Rebuild after changing a config plugin; an OTA JavaScript update cannot change native permissions or database libraries.

Important Ovok decisions​

  • The app uses an email/password patient flow. It does not need an OAuth redirect URI unless you later add an authentication flow that returns through a link.
  • expo-notifications schedules device-local notifications. It does not send a medication schedule to Ovok.
  • SQLCipher protects the app-owned offline cache/outbox at rest. It does not replace access control, device security, or a privacy review.

Expected result​

The blank Expo app launches in a custom development build, and its native configuration includes Expo Notifications and SQLCipher.

Common errors and troubleshooting​

  • Expo cannot resolve a native package: run npx expo install --fix, then rebuild.
  • The SQLite plugin appears configured but the app opens an ordinary database: confirm useSQLCipher: true is in the evaluated Expo config and rebuild the native app.
  • Notifications do not appear while the app is open: install the notification handler in step 7; Expo does not present foreground notifications by default without one.

Previous / Next​

Start: Medication Reminder tutorial overview · Continue to step 2: create and configure the Ovok project.