Skip to main content

Step 1: Create the React Native app

What we are building​

An Expo Router application that compiles for iOS and Android and contains the native dependencies for Ovok, persistent client storage, Bluetooth LE, and the language preference used later in the tutorial.

What you should already have​

  • Node.js and npm.
  • Xcode for iOS and/or Android Studio for Android.
  • A physical phone for BLE discovery and measurement tests.
  • The Native SDK installation guide for version-specific compatibility notes.

The minimum Ovok SDK versions validated for this tutorial are @ovok/core 0.4.27 and @ovok/native 1.10.6. Keep your lockfile and check peer compatibility when upgrading.

The implementation​

Create the Expo Router project and install dependencies​

npx create-expo-app@latest ovok-findrisc --template tabs
cd ovok-findrisc
npm install @ovok/core@^0.4.27 @ovok/native@^1.10.6 i18next react-i18next
npx expo install react-native-ble-plx react-native-permissions expo-secure-store expo-crypto expo-standard-web-crypto expo-dev-client expo-constants expo-router react-native-gesture-handler react-native-keyboard-controller react-native-paper react-native-safe-area-context react-native-svg expo-build-properties @react-native-async-storage/async-storage
npm install --save-dev jest-expo @types/jest

react-native-ble-plx is a native dependency. AsyncStorage will store a non-secret language preference and remembered device IDs. Ovok client credentials and tokens do not belong in app configuration.

Run the Ovok runtime bootstrap before Expo Router​

Create index.js in the project root:

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

polyfillOvokWebAPIs();
require("expo-router/entry");

Set the app entry in package.json:

{
"main": "index.js"
}

This is CommonJS intentionally. The polyfill must run before the app imports the client or native screens. It uses the Ovok-named runtime API; do not import deprecated initializer names.

Configure native permissions and build targets​

Use your existing bundle identifiers in app.config.ts:

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

const config: ExpoConfig = {
name: "Ovok FINDRISC",
slug: "ovok-findrisc",
plugins: [
"expo-router",
[
"@ovok/native",
{
bluetooth: {
bluetoothAlwaysPermission:
"Allow this app to connect to a supported blood-glucose meter.",
},
},
],
["react-native-permissions", { iosPermissions: ["Bluetooth"] }],
[
"expo-build-properties",
{
ios: { deploymentTarget: "16.4" },
android: { minSdkVersion: 26 },
},
],
"expo-secure-store",
],
ios: { bundleIdentifier: "com.example.ovokfindrisc" },
android: { package: "com.example.ovokfindrisc" },
};

export default config;

This tutorial scans only while the authenticated app is open. It does not configure background Bluetooth, HealthKit, Health Connect, or notifications. See the BTProvider permission behavior and native installation.

Add public sandbox configuration​

Create .env.example:

EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com
EXPO_PUBLIC_TENANT_CODE=replace-with-your-sandbox-tenant-code
EXPO_PUBLIC_FINDRISC_QUESTIONNAIRE_ID=replace-with-the-published-resource-id
EXPO_PUBLIC_FINDRISC_QUESTIONNAIRE_URL=replace-with-the-reviewed-canonical-url
EXPO_PUBLIC_FINDRISC_QUESTIONNAIRE_VERSION=replace-with-the-reviewed-version

Copy it to a local environment file and ignore that file in Git. Expo embeds EXPO_PUBLIC_ values in the client bundle, so put only public project configuration there—never passwords, private keys, or access tokens. The questionnaire canonical URL and version must match the clinically reviewed resource exactly.

Build a native development app​

Expo Go does not include the Bluetooth native module. Generate native projects and compile a development build:

npx expo prebuild
npx expo run:ios
npx expo run:android

You only need to run the target platform you are building now. Rebuild after changing a native plugin or permission. BLE testing needs a physical compatible meter and phone.

Add the scoring test script​

Add a Jest configuration at the project root:

module.exports = {
preset: "jest-expo",
testMatch: ["**/src/**/*.test.ts"],
};

Add this script to the existing scripts object in package.json:

{
"scripts": {
"test": "jest"
}
}

Step 5 adds the score tests. Keep the single existing scripts object when editing the Expo-generated package file.

Important Ovok decisions​

  • The sandbox URL and tenant code are public configuration. Patient credentials are not.
  • iOS usage text must explain the real Bluetooth purpose. Do not request background BLE access for this foreground tutorial.
  • The actual questionnaire ID, canonical URL, and version are supplied by your sandbox resource; they are not universal Ovok settings.
  • Native config changes require a new development build; an over-the-air JavaScript update cannot add native permissions.

Expected result​

The Expo template compiles as a native development app on at least one platform. The app opens without a runtime bootstrap error.

Common errors and troubleshooting​

  • BLE module not found: install the Expo-compatible BLE and permissions packages, run prebuild, then rebuild the app.
  • Permission prompt has no explanation: check the @ovok/native plugin text and iOS permission plugin, then rebuild.
  • Expo Go starts: launch the custom development build, not Expo Go.
  • Questionnaire configuration is blank: wait until step 2 to copy the resource ID, canonical URL, and version from the approved sandbox Questionnaire.

Previous / Next​

Guide overview · Next: create and configure the Ovok project