React Native · Expo · Turbo Module · New Architecture

On-device AI
No cloud

Bring Gemini Nano and Apple Foundation Models into your React Native or Expo app. No API key. No internet. No cloud costs. Everything runs on the device.

$yarn add react-native-gemini-nano
$ 0
API cost
2
functions to learn
100%
on-device

Why use it

01

Full privacy

User input never leaves the device. Ideal for medical, financial, and personal data apps.

02

Zero latency

No network round-trip. Inference runs directly on the device, even offline.

03

JSI direct bridge

Built on Turbo Modules + JSI. No legacy bridge overhead, no serialization cost.

04

Unlimited calls

No rate limits, no usage quotas, no monthly bills. Call as often as you need.

Get started

Requires a development build. This library uses native code (Turbo Module) and does not work with Expo Go.

1. Install the package

yarn add react-native-gemini-nano

2. Add the config plugin to app.json

{
  "expo": {
    "plugins": ["react-native-gemini-nano"]
  }
}

3. Rebuild your dev client

npx expo prebuild
npx expo run:android  # or run:ios
yarn add react-native-gemini-nano

iOS — install pods

cd ios && pod install

Enable New Architecture

# android/gradle.properties
newArchEnabled=true
# ios/Podfile
:new_arch_enabled => true

Real-world use cases

Translate text without sending it to a server

async function translate(text: string, targetLang: string) {
  const prompt = `Translate the following text to ${targetLang}.
Only return the translated text, nothing else.

Text: ${text}`;

  return generateText(prompt, {
    temperature: 0.2,  // low = accurate, consistent output
    maxTokens: 512,
  });
}

// usage
const result = await translate('Hello, how are you?', 'Korean');
// → "안녕하세요, 잘 지내시나요?"
temperature: 0.2 — Keep it low for translation. High temperature makes the model creative, which hurts accuracy.

Summarize long text into bullet points

async function summarize(article: string) {
  const prompt = `Summarize this article in 3 bullet points.
Each bullet point should be one sentence.
Use simple language.

Article:
${article}`;

  return generateText(prompt, {
    temperature: 0.4,
    maxTokens: 200,  // short output = fewer tokens needed
  });
}

// usage
const summary = await summarize(longArticleText);
// → "• React Native 0.75 introduces...
//    • The new architecture improves...
//    • Developers can now..."
maxTokens: 200 — For summaries the output is short. Setting a tight limit speeds up generation significantly.

Classify user reviews without a cloud API

type Sentiment = 'positive' | 'neutral' | 'negative';

async function getSentiment(review: string): Promise<Sentiment> {
  const prompt = `Classify the sentiment of this review.
Reply with exactly one word: positive, neutral, or negative.

Review: "${review}"`;

  const raw = await generateText(prompt, {
    temperature: 0.0,  // deterministic: same input → same output
    maxTokens: 5,     // we only need one word
  });

  const word = raw.trim().toLowerCase();
  return ['positive','neutral','negative'].includes(word)
    ? word as Sentiment : 'neutral';
}

// usage
const s = await getSentiment('This app crashes every time.');
// → "negative"
temperature: 0.0, maxTokens: 5 — For classification you want zero randomness and a one-word output. Fastest way to run the model.

Build a simple stateful chatbot

type Message = { role: 'user' | 'assistant'; content: string };

async function chat(history: Message[], userMessage: string) {
  const conversation = history
    .map(m => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`)
    .join('\n');

  const prompt = `You are a helpful assistant. Keep answers short.

${conversation}
User: ${userMessage}
Assistant:`;

  return (await generateText(prompt, {
    temperature: 0.8,  // higher = more natural-sounding
    maxTokens: 256,
  })).trim();
}

// usage
const history: Message[] = [];
const reply = await chat(history, 'What is React Native?');
history.push({ role: 'user', content: 'What is React Native?' });
history.push({ role: 'assistant', content: reply });
temperature: 0.8 — Slightly higher for chat makes replies feel less robotic. Keep history to the last 5–10 messages or you'll hit the token limit.

What runs on each platform

Android Gemini Nano via AICore

On Android, the library talks to Google AI Edge SDK (com.google.ai.edge.aicore). Gemini Nano is pre-installed on supported Pixel devices through Google Play Services — no model download needed. The model runs inside AICore, a sandboxed system service managed by Google.

// Kotlin — what the library does internally
val config = generationConfig {
  context = reactApplicationContext
  temperature = 0.7f
  topK = 16
  maxOutputTokens = 256
}
val model = GenerativeModel(generationConfig = config)
val response = model.generateContent(prompt)
// response.text → returned to JavaScript

⚠️ Requires Pixel 8 / 8a / 8 Pro or newer. Samsung Galaxy and other Android OEMs are not supported — AICore is a Google-exclusive feature.

iOS Apple Foundation Models

On iOS 26+, the library uses Apple's FoundationModels framework — the same on-device model that powers Apple Intelligence features like Writing Tools and Siri suggestions. No external download, it ships with the OS.

// Swift — what the library does internally
let session = LanguageModelSession()
let response = try await session.respond(to: prompt)
// response.content → returned to JavaScript via ObjC bridge

Requires iOS 26.0+. On older iOS, isAvailable() returns false automatically.

API

isAvailable(): Promise<boolean>

Returns whether the on-device model is ready on the current device. Always call this before generateText.

Return Description
true Model available — safe to generate
false Device not supported or model not ready
generateText(prompt, options?): Promise<string>

Runs on-device inference and returns the generated text string.

Option Type Default Description
temperature number 0.7 Randomness — 0 = focused, 1 = creative
maxTokens number 256 Maximum output token count

Start building

One line to install. Two functions to use.

$ yarn add react-native-gemini-nano