React Native / Expo

@noryen/sdk is plain TypeScript with no native modules—it runs in React Native and Expo the same as in Node, as long as you have fetch (Hermes / modern RN do).

Install

npm install @noryen/sdk (or yarn / pnpm) in your app package.

API key in the client

Expo public env vars (for example EXPO_PUBLIC_NORYEN_API_KEY) are bundled into the app—anyone with the binary can extract them. Prefer a backend or Edge function that holds NORYEN_API_KEY if you need strict secrecy; use the client-only flow below when you accept that tradeoff (similar to other client analytics keys).

Initialize once

lib/noryen.ts
// lib/noryen.ts
import { noryen } from "@noryen/sdk";
let initialized = false;
export function ensureNoryenInitialized() {
if (initialized) {
return;
}
const apiKey = process.env.EXPO_PUBLIC_NORYEN_API_KEY;
if (!apiKey) {
initialized = true;
return;
}
noryen.init({ apiKey, debug: __DEV__ });
initialized = true;
}
ensureNoryenInitialized();
export { noryen };

Import the module from your root layout so initialization runs at app startup:

app/_layout.tsx
// app/_layout.tsx
import "@/lib/noryen";
// …rest of layout (providers, fonts, etc.)

Global metadata

Use noryen.setContext() for fields you want on every trace (platform, app version, environment):

providers/app-context.tsx
// providers/app-context.tsx (example)
import { useEffect } from "react";
import { Platform } from "react-native";
import Constants from "expo-constants";
import { noryen } from "@/lib/noryen";
export function NoryenAppContext() {
useEffect(() => {
noryen.setContext({
platform: Platform.OS,
appVersion: Constants.expoConfig?.version,
});
}, []);
return null;
}

Manual track()

If you call OpenRouter or another HTTP API yourself, emit traces with noryen.track(). Attach TrackContext when you have documents or retrieval data to record:

lib/ai/generate-plan.ts
import { noryen } from "@/lib/noryen";
const model = "google/gemini-2.0-flash-001";
async function generatePlan(prompt: string, inputData: string) {
const started = Date.now();
try {
const result = await callOpenRouter(prompt);
noryen.track({
model,
provider: "openrouter",
success: true,
prompt,
response: result,
latency: Date.now() - started,
metadata: { feature: "personal_plan_generation" },
context: {
documents: [{ content: inputData, source: "app.health_data" }],
retrieval: { query: "user health data", method: "manual", k: 1 },
},
});
return result;
} catch (err) {
noryen.track({
model,
provider: "openrouter",
success: false,
error: err instanceof Error ? err.message : String(err),
prompt,
response: "",
latency: Date.now() - started,
});
throw err;
}
}
For the full set of fields on context (documents, retrieval, instructions) see TrackContext.

All installation guides