1. Create the React Native app
What we are building
An Expo Router app that can run the Ovok Native SDK and later request read-only sleep, step-count and resting-heart-rate access from HealthKit or Health Connect.
What you should already have
- Node.js and the package manager used by your team.
- Xcode for iOS builds, or Android Studio and an Android target.
- The Native SDK installation guide open for the current peer-dependency matrix.
The implementation
Create the project and add Ovok:
npx create-expo-app@latest ovok-healthspan --template tabs
cd ovok-healthspan
npm install @ovok/core @ovok/native i18next react-i18next formik yup
npx expo install expo-dev-client expo-secure-store expo-standard-web-crypto @react-native-async-storage/async-storage react-native-ble-plx react-native-permissions react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-keyboard-controller react-native-paper react-native-svg @kingstinct/react-native-healthkit expo-health-connect react-native-health-connect
The native package has required peers for its published app shell; HealthKit and Health Connect are optional integrations but are included here because later steps use them. If your application imports a narrower set of entry points, follow the installation matrix and install only the peers required by those imports.
Set the Expo entry point to the runtime bootstrap before the router. In package.json:
{
"main": "index.js"
}
Create index.js:
const { polyfillOvokWebAPIs } = require("@ovok/native/polyfills");
polyfillOvokWebAPIs();
require("expo-router/entry");
Add the native capabilities the tutorial uses in app.config.ts. This is a minimal integration fragment; keep your existing Expo config fields:
const config = {
expo: {
plugins: [
[
"@ovok/native",
{
healthKit: true,
healthConnect: true,
},
],
],
ios: {
infoPlist: {
NSHealthShareUsageDescription:
"Allow this app to import selected sleep, movement and resting-heart-rate records for your wellbeing history.",
},
},
android: {
minSdkVersion: 28,
permissions: [
"android.permission.health.READ_SLEEP",
"android.permission.health.READ_STEPS",
"android.permission.health.READ_RESTING_HEART_RATE",
],
},
},
};
export default config;
Use read access only. Do not add HealthKit write usage text or Health Connect write permissions: this tutorial never writes data back to the phone's health store. Explain the permission in your own product language and request it only when the member chooses to connect.
Create .env.local:
EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com
EXPO_PUBLIC_TENANT_CODE=your-sandbox-tenant
These values are public configuration embedded in the app bundle. Never place a secret or private credential in an EXPO_PUBLIC_ variable.
Build a native development app:
npx expo prebuild
npx expo run:ios
For Android, use npx expo run:android. Expo Go does not include all of the required native modules; use a development/native build. Rebuild after changing native dependencies or config plugins.
Important Ovok decisions
- The SDK runtime bootstrap runs before Expo Router imports application code.
- HealthKit and Health Connect are separate platform APIs; each requires a native build and platform permission setup.
- Android Health Connect requires Android API 28 or newer.
- The app requests read-only access only for sleep sessions, step counts and resting heart rate, which are used later.
- App-owned UI translation text will come from Ovok CMS in step 3 and step 10, not translation JSON files.
Expected result
The empty Expo app builds for at least one native target. Keep a development build installed; step 4 adds the HealthKit / Health Connect provider and import screen.
Common errors and troubleshooting
| Symptom | Check |
|---|---|
| Expo reports a missing native module | Rebuild the development app after installing the peer or changing config. |
| Health Connect is unavailable on Android | Confirm API 28+, Google Play services and Health Connect availability on the target device. |
| The SDK fails before the first screen | Confirm index.js calls polyfillOvokWebAPIs() before the Expo Router entry. |
| A value appears in the app bundle unexpectedly | Remove credentials from every EXPO_PUBLIC_ variable. |