react-native-ai-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AiCore.podspec ADDED
@@ -0,0 +1,20 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "AiCore"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "https://github.com/albertofernandezroda/react-native-ai-core.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
17
+ s.private_header_files = "ios/**/*.h"
18
+
19
+ install_modules_dependencies(s)
20
+ end
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alberto Fernandez
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,273 @@
1
+ # react-native-ai-core
2
+
3
+ [![npm version](https://img.shields.io/npm/v/react-native-ai-core.svg)](https://www.npmjs.com/package/react-native-ai-core)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
5
+ [![Platform: Android](https://img.shields.io/badge/Platform-Android-green.svg)](https://developer.android.com)
6
+ [![New Architecture](https://img.shields.io/badge/New%20Architecture-TurboModule-blue.svg)](https://reactnative.dev/docs/the-new-architecture/landing-page)
7
+
8
+ > **⚠️ Development in Progress** — This library is under active development. APIs may change between minor versions. Not recommended for production use yet.
9
+
10
+ On-device LLM inference for React Native using **Gemini Nano** via Google's AI Edge SDKs. Runs entirely on-device — no internet connection required, full privacy.
11
+
12
+ Supports two backends:
13
+ - **ML Kit AICore** (`genai-prompt`) — hardware-accelerated via the device NPU (Pixel 9+, Android 14+)
14
+ - **MediaPipe Tasks GenAI** — file-based inference using a local `.bin` model (any Android device with API ≥ 26)
15
+
16
+ Built with TurboModules (New Architecture), JSI bridge, zero-overhead streaming via `NativeEventEmitter`.
17
+
18
+ ---
19
+
20
+ ## Requirements
21
+
22
+ | | Minimum |
23
+ |---|---|
24
+ | React Native | 0.76+ (New Architecture) |
25
+ | Android API | 26 (Android 8) |
26
+ | Kotlin | 1.9+ |
27
+
28
+ **For ML Kit AICore backend:** Pixel 9 or any device with `Feature.AI_CORE` support (Android 14+, NPU required).
29
+
30
+ **For MediaPipe backend:** Any Android device API ≥ 26. Requires a downloaded Gemini Nano `.bin` model file on the device.
31
+
32
+ ---
33
+
34
+ ## Installation
35
+
36
+ ```sh
37
+ npm install react-native-ai-core
38
+ # or
39
+ yarn add react-native-ai-core
40
+ ```
41
+
42
+ ### Android setup
43
+
44
+ Add to `android/gradle.properties`:
45
+
46
+ ```properties
47
+ minSdkVersion=26
48
+ ```
49
+
50
+ No additional permissions are required. The native module is auto-linked.
51
+
52
+ ---
53
+
54
+ ## Quick Start
55
+
56
+ ```tsx
57
+ import AICore from 'react-native-ai-core';
58
+
59
+ // 1. Check availability
60
+ const status = await AICore.checkAvailability();
61
+ // 'AVAILABLE' | 'AVAILABLE_NPU' | 'NEED_DOWNLOAD' | 'UNSUPPORTED'
62
+
63
+ // 2. Initialize the engine
64
+ // Pass an empty string '' to use the ML Kit AICore backend (Pixel 9+).
65
+ // Pass an absolute path to a .bin file to use the MediaPipe backend.
66
+ await AICore.initialize(''); // AICore native (NPU)
67
+
68
+ // 3. Generate a response
69
+ const answer = await AICore.generateResponse('What is React Native?');
70
+ console.log(answer);
71
+
72
+ // 4. Release resources when done
73
+ await AICore.release();
74
+ ```
75
+
76
+ ### Streaming
77
+
78
+ ```tsx
79
+ const unsubscribe = AICore.generateResponseStream('Explain JSI in detail', {
80
+ onToken: (token, done) => {
81
+ process.stdout.write(token);
82
+ if (done) console.log('\n[stream ended]');
83
+ },
84
+ onComplete: () => console.log('Done!'),
85
+ onError: (err) => console.error(err.code, err.message),
86
+ });
87
+
88
+ // Cancel subscriptions when component unmounts
89
+ return () => unsubscribe();
90
+ ```
91
+
92
+ ### Multi-turn conversation
93
+
94
+ The native engine keeps a conversation history automatically. Each call to `generateResponse` / `generateResponseStream` includes previous turns as context.
95
+
96
+ To start a fresh conversation without releasing the model:
97
+
98
+ ```tsx
99
+ await AICore.resetConversation();
100
+ ```
101
+
102
+ ---
103
+
104
+ ## API Reference
105
+
106
+ ### `initialize(modelPath: string): Promise<boolean>`
107
+
108
+ Initializes the inference engine.
109
+
110
+ | Argument | Type | Description |
111
+ |---|---|---|
112
+ | `modelPath` | `string` | Pass `''` to use ML Kit AICore (native NPU). Pass an absolute path to a `.bin` file to use MediaPipe. |
113
+
114
+ Returns `true` on success. Throws on failure.
115
+
116
+ **Error codes:**
117
+ - `MODEL_NOT_FOUND` — file at `modelPath` does not exist
118
+ - `NPU_UNSUPPORTED` — device NPU is not compatible
119
+ - `INIT_FAILED` — engine failed to start
120
+
121
+ ---
122
+
123
+ ### `generateResponse(prompt: string): Promise<string>`
124
+
125
+ Generates a complete response synchronously (waits for the full output).
126
+
127
+ ```tsx
128
+ const response = await AICore.generateResponse('Tell me a joke');
129
+ ```
130
+
131
+ **Error codes:**
132
+ - `NOT_INITIALIZED` — `initialize()` was not called first
133
+ - `GENERATION_ERROR` — model failed during inference
134
+
135
+ ---
136
+
137
+ ### `generateResponseStream(prompt: string, callbacks: StreamCallbacks): () => void`
138
+
139
+ Generates a response token by token via streaming. Returns a cleanup function to remove event listeners.
140
+
141
+ ```tsx
142
+ const StreamCallbacks = {
143
+ onToken: (token: string, done: boolean) => void,
144
+ onComplete: () => void,
145
+ onError: (error: AIError) => void,
146
+ }
147
+ ```
148
+
149
+ Events are delivered through `NativeEventEmitter`:
150
+ - `AICore_streamToken` → `{ token: string, done: boolean }`
151
+ - `AICore_streamComplete` → `{}`
152
+ - `AICore_streamError` → `{ code: string, message: string }`
153
+
154
+ ---
155
+
156
+ ### `checkAvailability(): Promise<AvailabilityStatus>`
157
+
158
+ Returns the current availability status of Gemini Nano on this device.
159
+
160
+ | Value | Meaning |
161
+ |---|---|
162
+ | `'AVAILABLE'` | Model is ready to use (file-based) |
163
+ | `'AVAILABLE_NPU'` | Model is ready and hardware-accelerated (AICore) |
164
+ | `'NEED_DOWNLOAD'` | Device is compatible but model needs to be downloaded |
165
+ | `'UNSUPPORTED'` | Device does not meet minimum requirements |
166
+
167
+ ---
168
+
169
+ ### `release(): Promise<void>`
170
+
171
+ Releases the model from NPU/CPU memory. Call this in your cleanup effect.
172
+
173
+ ```tsx
174
+ useEffect(() => {
175
+ AICore.initialize('');
176
+ return () => { AICore.release(); };
177
+ }, []);
178
+ ```
179
+
180
+ ---
181
+
182
+ ### `resetConversation(): Promise<void>`
183
+
184
+ Clears the conversation history in the native engine without releasing the model. The next call to `generateResponse` will start a new conversation.
185
+
186
+ ---
187
+
188
+ ## Types
189
+
190
+ ```typescript
191
+ export type AvailabilityStatus =
192
+ | 'AVAILABLE'
193
+ | 'AVAILABLE_NPU'
194
+ | 'NEED_DOWNLOAD'
195
+ | 'UNSUPPORTED';
196
+
197
+ export interface StreamCallbacks {
198
+ onToken: (token: string, done: boolean) => void;
199
+ onComplete: () => void;
200
+ onError: (error: AIError) => void;
201
+ }
202
+
203
+ export interface AIError {
204
+ code: string;
205
+ message: string;
206
+ }
207
+ ```
208
+
209
+ ---
210
+
211
+ ## `useAICore` Hook
212
+
213
+ A ready-to-use React hook is available in the example app as a reference implementation. It handles:
214
+
215
+ - Availability check on mount
216
+ - Engine lifecycle (initialize / release)
217
+ - Streaming with incremental message updates
218
+ - Conversation history reset on clear
219
+ - Error state management
220
+
221
+ See [`example/src/hooks/useAICore.ts`](example/src/hooks/useAICore.ts).
222
+
223
+ ---
224
+
225
+ ## Backends
226
+
227
+ ### ML Kit AICore (native NPU)
228
+
229
+ Used when `modelPath = ''`. Requires a Pixel 9 or compatible device with Android's [AICore](https://developer.android.com/ml/gemini-nano) feature. The model runs fully on the device NPU with no file management needed — Google handles the model download automatically via system updates.
230
+
231
+ Dependency: `com.google.mlkit:genai-prompt:1.0.0-beta2`
232
+
233
+ ### MediaPipe Tasks GenAI (file-based)
234
+
235
+ Used when `modelPath` points to a valid `.bin` file. Works on any Android device with API ≥ 26. You are responsible for placing the model file on the device (e.g., via `adb push` or a download manager).
236
+
237
+ ```sh
238
+ adb push gemini-nano.bin /data/local/tmp/gemini-nano.bin
239
+ ```
240
+
241
+ Dependency: `com.google.mediapipe:tasks-genai:0.10.22`
242
+
243
+ ---
244
+
245
+ ## Roadmap
246
+
247
+ - [ ] iOS support (Core ML / Apple Neural Engine)
248
+ - [ ] Automatic model download manager
249
+ - [ ] Model quantization options
250
+ - [ ] System prompt / persona configuration
251
+ - [ ] Token count estimation
252
+ - [ ] Abort/cancel streaming mid-generation
253
+ - [ ] Web support (WebGPU / WASM)
254
+
255
+ ---
256
+
257
+ ## Contributing
258
+
259
+ Contributions, issues and feature requests are welcome.
260
+
261
+ - [Development workflow](CONTRIBUTING.md#development-workflow)
262
+ - [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
263
+ - [Code of conduct](CODE_OF_CONDUCT.md)
264
+
265
+ ---
266
+
267
+ ## License
268
+
269
+ MIT © [Alberto Fernandez](https://github.com/albertofernandezroda)
270
+
271
+ ---
272
+
273
+ <sub>Built with [react-native-builder-bob](https://github.com/callstack/react-native-builder-bob)</sub>
@@ -0,0 +1,76 @@
1
+ buildscript {
2
+ ext.AiCore = [
3
+ kotlinVersion: "2.0.21",
4
+ minSdkVersion: 26,
5
+ compileSdkVersion: 36,
6
+ targetSdkVersion: 36
7
+ ]
8
+
9
+ ext.getExtOrDefault = { prop ->
10
+ if (rootProject.ext.has(prop)) {
11
+ return rootProject.ext.get(prop)
12
+ }
13
+
14
+ return AiCore[prop]
15
+ }
16
+
17
+ repositories {
18
+ google()
19
+ mavenCentral()
20
+ }
21
+
22
+ dependencies {
23
+ classpath "com.android.tools.build:gradle:8.7.2"
24
+ // noinspection DifferentKotlinGradleVersion
25
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
26
+ }
27
+ }
28
+
29
+
30
+ apply plugin: "com.android.library"
31
+ apply plugin: "kotlin-android"
32
+
33
+ apply plugin: "com.facebook.react"
34
+
35
+ android {
36
+ namespace "com.aicore"
37
+
38
+ compileSdkVersion getExtOrDefault("compileSdkVersion")
39
+
40
+ defaultConfig {
41
+ minSdkVersion getExtOrDefault("minSdkVersion")
42
+ targetSdkVersion getExtOrDefault("targetSdkVersion")
43
+ }
44
+
45
+ buildFeatures {
46
+ buildConfig true
47
+ }
48
+
49
+ buildTypes {
50
+ release {
51
+ minifyEnabled false
52
+ }
53
+ }
54
+
55
+ lint {
56
+ disable "GradleCompatible"
57
+ }
58
+
59
+ compileOptions {
60
+ sourceCompatibility JavaVersion.VERSION_1_8
61
+ targetCompatibility JavaVersion.VERSION_1_8
62
+ }
63
+ }
64
+
65
+ dependencies {
66
+ implementation "com.facebook.react:react-android"
67
+
68
+ // Google AI Edge — MediaPipe Tasks GenAI (modelo de archivo local)
69
+ implementation "com.google.mediapipe:tasks-genai:0.10.22"
70
+
71
+ // ML Kit GenAI Prompt API — accede a Gemini Nano vía AICore (Pixel 8+, sin archivo)
72
+ implementation "com.google.mlkit:genai-prompt:1.0.0-beta2"
73
+
74
+ // Coroutines (requerido por ML Kit Flow API)
75
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"
76
+ }
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>