@capgo/capacitor-llm
v8.1.3
Published
Adds support for LLM locally runned for Capacitor
Maintainers
Readme
@capgo/capacitor-llm
On-device LLM support for Capacitor.
Current platform strategy:
- iOS: Apple Intelligence by default, plus LiteRT-LM
.litertlmcustom models in SwiftPM integrations when the path ends in.litertlmormodelType: 'litertlm'is passed - Android: Gemini Nano system model on supported devices where it is already available, LiteRT-LM for
.litertlmbundles, and a compatibility fallback for legacy MediaPipe.taskmodels - Web: Gemma 4 web models through
@mediapipe/tasks-genai
Documentation
The most complete plugin docs are available at capgo.app/docs/plugins/llm.
Compatibility
| Plugin version | Capacitor compatibility | Maintained | | -------------- | ----------------------- | ---------- | | v8.. | v8.. | ✅ | | v7.. | v7.. | On demand | | v6.. | v6.. | ❌ | | v5.. | v5.. | ❌ |
Note: The plugin major version follows the Capacitor major version. Use the version that matches your Capacitor installation.
Installation
npm install @capgo/capacitor-llm
npx cap syncIf you use the web implementation, also install the MediaPipe peer dependency:
npm install @mediapipe/tasks-genaiModel Setup
iOS
Recommended path:
- Use Apple Intelligence with
path: 'Apple Intelligence' - Requires iOS 26.0+
Custom iOS LiteRT-LM path:
- Available only when the plugin is integrated into the iOS app through Swift Package Manager
- Uses the official LiteRT-LM Swift API and prebuilt iOS xcframework for
.litertlmmodels - Selected only when the path ends in
.litertlmormodelType: 'litertlm'is passed - CocoaPods builds keep Apple Intelligence and the legacy MediaPipe
.taskcompatibility path - Other custom iOS model types keep the legacy MediaPipe compatibility path for backward compatibility
Example:
import { CapgoLLM } from '@capgo/capacitor-llm';
await CapgoLLM.setModel({ path: 'Apple Intelligence' });
const chat = await CapgoLLM.createChat();Android
Recommended path:
- Use Gemini Nano with
path: 'Gemini Nano'when the Android device already has it available through AICore - Use LiteRT-LM
.litertlmbundles - Gemma 4 E2B and E4B are good default examples
- Models are available from the public
litert-communityHugging Face repos
Gemini Nano system model example:
await CapgoLLM.setModel({ path: 'Gemini Nano' });
const chat = await CapgoLLM.createChat();Quickstart with a downloaded Gemma 4 model:
import { CapgoLLM } from '@capgo/capacitor-llm';
const result = await CapgoLLM.downloadModel({
url: 'https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm/resolve/main/gemma-4-E2B-it.litertlm?download=true',
filename: 'gemma-4-E2B-it.litertlm',
});
await CapgoLLM.setModel({
path: result.path,
modelType: 'litertlm',
maxTokens: 4096,
topk: 40,
temperature: 0.8,
});
const chat = await CapgoLLM.createChat();Bundled asset example:
await CapgoLLM.setModel({
path: '/android_asset/gemma-4-E2B-it.litertlm',
modelType: 'litertlm',
maxTokens: 4096,
});Legacy compatibility:
- Existing Android
.taskmodels still load through the compatibility path - New integrations should prefer
.litertlm
Web
The web implementation uses @mediapipe/tasks-genai with web-ready model artifacts.
Gemma 4 web models are published next to the mobile LiteRT-LM bundles and use *-web.task.
Example:
await CapgoLLM.setModel({
path: 'https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm/resolve/main/gemma-4-E2B-it-web.task?download=true',
modelType: 'task',
maxTokens: 4096,
});Usage
import { CapgoLLM } from '@capgo/capacitor-llm';
const { readiness } = await CapgoLLM.getReadiness();
console.log('LLM readiness:', readiness);
const { id } = await CapgoLLM.createChat();
await CapgoLLM.addListener('textFromAi', (event) => {
console.log('chunk', event.text);
});
await CapgoLLM.addListener('aiFinished', ({ chatId }) => {
console.log('finished', chatId);
});
await CapgoLLM.sendMessage({
chatId: id,
message: 'Explain why local inference is useful on mobile.',
});Notes
- Android now prefers LiteRT-LM and Gemma 4 style
.litertlmbundles. - iOS LiteRT-LM custom-model support now uses the official LiteRT-LM Swift API and prebuilt iOS binaries, is available only in SwiftPM integrations of this plugin, and is selected only for explicit
.litertlmmodels. - CocoaPods builds on iOS should use Apple Intelligence or the legacy MediaPipe
.taskcompatibility path. - Web uses Gemma 4
*-web.taskartifacts through@mediapipe/tasks-genai. - Apple Intelligence remains the preferred default on iOS where available.
createChat()sendMessage(...)getReadiness()setModel(...)downloadModel(...)addListener('textFromAi', ...)addListener('aiFinished', ...)addListener('generationError', ...)addListener('downloadProgress', ...)addListener('readinessChange', ...)getPluginVersion()- Interfaces
LLM Plugin interface for interacting with on-device language models
createChat()
createChat() => Promise<{ id: string; instructions?: string; }>Creates a new chat session
Returns: Promise<{ id: string; instructions?: string; }>
sendMessage(...)
sendMessage(options: { chatId: string; message: string; }) => Promise<void>Sends a message to the AI in a specific chat session
| Param | Type | Description |
| ------------- | ------------------------------------------------- | --------------------------------- |
| options | { chatId: string; message: string; } | - The chat id and message to send |
getReadiness()
getReadiness() => Promise<{ readiness: string; }>Gets the readiness status of the LLM
Returns: Promise<{ readiness: string; }>
setModel(...)
setModel(options: ModelOptions) => Promise<void>Sets the model configuration
- iOS: Use "Apple Intelligence" as path for the system model. Custom LiteRT-LM
.litertlmmodels are supported on iOS only when this plugin is integrated through Swift Package Manager, and are selected only whenmodelType: 'litertlm'is passed or the path ends in.litertlm. - Android: Use "Gemini Nano" for the AICore system model on supported devices where it is already available. Prefer LiteRT-LM
.litertlmbundles for custom models; legacy MediaPipe.taskmodels are still supported - Web: Provide a web-ready model asset for
@mediapipe/tasks-genaisuch as Gemma 4*-web.task
| Param | Type | Description |
| ------------- | ----------------------------------------------------- | ------------------------- |
| options | ModelOptions | - The model configuration |
downloadModel(...)
downloadModel(options: DownloadModelOptions) => Promise<DownloadModelResult>Downloads a model from a URL and saves it to the appropriate location
- iOS: Downloads to the app's documents directory
- Android: Downloads to the app's files directory
| Param | Type | Description |
| ------------- | --------------------------------------------------------------------- | ---------------------------- |
| options | DownloadModelOptions | - The download configuration |
Returns: Promise<DownloadModelResult>
addListener('textFromAi', ...)
addListener(eventName: 'textFromAi', listenerFunc: (event: TextFromAiEvent) => void) => Promise<{ remove: () => Promise<void>; }>Adds a listener for text received from AI
| Param | Type | Description |
| ------------------ | ------------------------------------------------------------------------------- | ----------------------------------- |
| eventName | 'textFromAi' | - Event name 'textFromAi' |
| listenerFunc | (event: TextFromAiEvent) => void | - Callback function for text events |
Returns: Promise<{ remove: () => Promise<void>; }>
addListener('aiFinished', ...)
addListener(eventName: 'aiFinished', listenerFunc: (event: AiFinishedEvent) => void) => Promise<{ remove: () => Promise<void>; }>Adds a listener for AI completion events
| Param | Type | Description |
| ------------------ | ------------------------------------------------------------------------------- | ------------------------------------- |
| eventName | 'aiFinished' | - Event name 'aiFinished' |
| listenerFunc | (event: AiFinishedEvent) => void | - Callback function for finish events |
Returns: Promise<{ remove: () => Promise<void>; }>
addListener('generationError', ...)
addListener(eventName: 'generationError', listenerFunc: (event: GenerationErrorEvent) => void) => Promise<{ remove: () => Promise<void>; }>Adds a listener for generation failures that happen after streaming starts
| Param | Type | Description |
| ------------------ | ----------------------------------------------------------------------------------------- | ----------------------------------------- |
| eventName | 'generationError' | - Event name 'generationError' |
| listenerFunc | (event: GenerationErrorEvent) => void | - Callback function for generation errors |
Returns: Promise<{ remove: () => Promise<void>; }>
addListener('downloadProgress', ...)
addListener(eventName: 'downloadProgress', listenerFunc: (event: DownloadProgressEvent) => void) => Promise<{ remove: () => Promise<void>; }>Adds a listener for model download progress events
| Param | Type | Description |
| ------------------ | ------------------------------------------------------------------------------------------- | --------------------------------------- |
| eventName | 'downloadProgress' | - Event name 'downloadProgress' |
| listenerFunc | (event: DownloadProgressEvent) => void | - Callback function for progress events |
Returns: Promise<{ remove: () => Promise<void>; }>
addListener('readinessChange', ...)
addListener(eventName: 'readinessChange', listenerFunc: (event: ReadinessChangeEvent) => void) => Promise<{ remove: () => Promise<void>; }>Adds a listener for readiness status changes
| Param | Type | Description |
| ------------------ | ----------------------------------------------------------------------------------------- | ---------------------------------------- |
| eventName | 'readinessChange' | - Event name 'readinessChange' |
| listenerFunc | (event: ReadinessChangeEvent) => void | - Callback function for readiness events |
Returns: Promise<{ remove: () => Promise<void>; }>
getPluginVersion()
getPluginVersion() => Promise<{ version: string; }>Get the native Capacitor plugin version.
Returns: Promise<{ version: string; }>
Since: 1.0.0
Interfaces
ModelOptions
Model configuration options
Only path is required. All other properties are optional overrides.
| Prop | Type | Description | Since |
| ----------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| path | string | Model path, "Apple Intelligence" for the Apple system model on iOS, or "Gemini Nano" for the Android AICore system model when already available on the device. On iOS, custom .litertlm models require the plugin to be integrated through Swift Package Manager. Gemma 4 examples use .litertlm on mobile and *-web.task on web. | |
| modelType | string | Optional. Model file type/extension (for example task, bin, litertlm, or gemini-nano). If not provided, it is extracted from the path. On iOS, LiteRT-LM is selected only when this resolves to litertlm; all other custom types keep the legacy MediaPipe compatibility path. | |
| maxTokens | number | Maximum number of tokens the model handles | |
| topk | number | Number of tokens the model considers at each step | |
| temperature | number | Amount of randomness in generation (0.0-1.0) | |
| randomSeed | number | Optional. Random seed for generation. | |
| backend | 'gpu' | 'cpu' | Optional. LiteRT-LM engine backend for iOS (SwiftPM) and Android. Use cpu for stable long generations. When omitted, iOS prefers CPU then falls back to GPU; Android uses CPU. | 8.2.0 |
DownloadModelResult
Result of model download
| Prop | Type | Description |
| ------------------- | ------------------- | ------------------------------------------------------- |
| path | string | Path where the model was saved |
| companionPath | string | Path where the companion file was saved (if applicable) |
DownloadModelOptions
Options for downloading a model
Only url is required. companionUrl and filename are optional.
| Prop | Type | Description |
| ------------------ | ------------------- | ---------------------------------------------------------- |
| url | string | URL of the model file to download |
| companionUrl | string | Optional: URL of a companion file for legacy model formats |
| filename | string | Optional: Custom filename (defaults to filename from URL) |
TextFromAiEvent
Event data for text received from AI
| Prop | Type | Description |
| ------------- | -------------------- | -------------------------------------------------------------------------- |
| text | string | The text content from AI - this is an incremental chunk, not the full text |
| chatId | string | The chat session ID |
| isChunk | boolean | Whether this is a complete chunk (true) or partial streaming data (false) |
AiFinishedEvent
Event data for AI completion
| Prop | Type | Description |
| ------------ | ------------------- | --------------------------------- |
| chatId | string | The chat session ID that finished |
GenerationErrorEvent
Event data for generation failures
chatId is optional and may be omitted when the failure is not tied to a specific chat.
| Prop | Type | Description |
| ------------ | ------------------- | ---------------------------------------------------------- |
| chatId | string | Optional. The chat session ID that failed, when available. |
| error | string | Error message describing the failure |
DownloadProgressEvent
Event data for download progress
| Prop | Type | Description |
| --------------------- | ------------------- | ---------------------------------------- |
| progress | number | Percentage of download completed (0-100) |
| totalBytes | number | Total bytes to download |
| downloadedBytes | number | Bytes downloaded so far |
ReadinessChangeEvent
Event data for readiness status changes
| Prop | Type | Description |
| --------------- | ------------------- | -------------------- |
| readiness | string | The readiness status |
Example App
The repo includes an example-app/ that demonstrates:
- Apple Intelligence on iOS
- Gemma 4 LiteRT-LM model downloads on Android
See example-app/README.md for local setup instructions.
