Getting Started
Installation
Section titled “Installation”npm install @capgo/capacitor-llmnpx cap syncyarn add @capgo/capacitor-llmnpx cap syncpnpm add @capgo/capacitor-llmnpx cap syncbun add @capgo/capacitor-llmnpx cap syncPlatform Configuration
Section titled “Platform Configuration”iOS Configuration
Section titled “iOS Configuration”- iOS 26.0+: Uses Apple Intelligence by default (no model needed) - Recommended
- iOS < 26.0: Requires MediaPipe custom models (experimental, may have compatibility issues)
For custom models on older iOS versions, place model files in your iOS app bundle through Xcode’s “Copy Bundle Resources”.
Android Configuration
Section titled “Android Configuration”Place model files in your Android assets folder:
android/app/src/main/assets/You need both files for Android:
.taskfile (main model).litertlmfile (companion file)
Download from Kaggle Gemma models → “LiteRT (formerly TFLite)” tab
Recommended Models
Section titled “Recommended Models”For Android (Gemma-3 Models)
Section titled “For Android (Gemma-3 Models)”- Gemma 3 270M - Smallest, most efficient for mobile (~240-400MB) - Recommended
- Gemma 3 1B - Larger text generation model (~892MB-1.5GB)
Download from Kaggle Gemma models → Click “LiteRT (formerly TFLite)” tab
For iOS
Section titled “For iOS”- Apple Intelligence (iOS 26.0+) - Built-in, no download needed - Recommended
- Gemma-2 2B (experimental) - May have compatibility issues with
.taskformat
For custom iOS models, download from Hugging Face MediaPipe models
Import the plugin and initialize:
import { CapgoLLM } from '@capgo/capacitor-llm';import { Capacitor } from '@capacitor/core';
// Check if LLM is readyconst { readiness } = await CapgoLLM.getReadiness();console.log('LLM readiness:', readiness);
// Set the model based on platformconst platform = Capacitor.getPlatform();if (platform === 'ios') { // iOS: Use Apple Intelligence (default) await CapgoLLM.setModel({ path: 'Apple Intelligence' });} else { // Android: Use MediaPipe model await CapgoLLM.setModel({ path: '/android_asset/gemma-3-270m-it-int8.task' });}
// Create a chat sessionconst { id: chatId } = await CapgoLLM.createChat();
// Listen for AI responsesCapgoLLM.addListener('textFromAi', (event) => { console.log('AI response:', event.text);});
// Listen for completionCapgoLLM.addListener('aiFinished', (event) => { console.log('AI completed response');});
// Send a messageawait CapgoLLM.sendMessage({ chatId, message: 'Hello! How are you today?'});Advanced Features
Section titled “Advanced Features”Download Models
Section titled “Download Models”// Download a model from URLawait CapgoLLM.downloadModel({ url: 'https://example.com/model.task', filename: 'model.task'});
// For Android, download both .task and .litertlm filesawait CapgoLLM.downloadModel({ url: 'https://example.com/gemma-3-270m-it-int8.task', companionUrl: 'https://example.com/gemma-3-270m-it-int8.litertlm', filename: 'gemma-3-270m-it-int8.task'});
// Listen for download progressCapgoLLM.addListener('downloadProgress', (event) => { console.log(`Download progress: ${event.progress}%`); console.log(`Downloaded: ${event.downloadedBytes} / ${event.totalBytes}`);});Model Management
Section titled “Model Management”// Set a specific model with configurationawait CapgoLLM.setModel({ path: '/android_asset/gemma-3-270m-it-int8.task', maxTokens: 2048, topk: 40, temperature: 0.8});
// Check readinessconst { readiness } = await CapgoLLM.getReadiness();if (readiness === 'ready') { // Model is loaded and ready}
// Listen for readiness changesCapgoLLM.addListener('readinessChange', (event) => { console.log('Readiness changed:', event.readiness);});API Methods
Section titled “API Methods”createChat()
Section titled “createChat()”Create a new chat session.
const { id: chatId } = await CapgoLLM.createChat();Returns: Promise<{ id: string; instructions?: string }>
sendMessage(…)
Section titled “sendMessage(…)”Send a message to the LLM.
await CapgoLLM.sendMessage({ chatId: 'chat-id', message: 'What is the weather like?'});| Param | Type | Description |
|---|---|---|
chatId | string | Chat session ID |
message | string | Message to send |
getReadiness()
Section titled “getReadiness()”Check if the LLM is ready to use.
const { readiness } = await CapgoLLM.getReadiness();Returns: Promise<{ readiness: string }>
Possible values:
ready- Model is loaded and readyloading- Model is being loadednot_ready- Model not yet loadederror- Error loading model
setModel(…)
Section titled “setModel(…)”Set the model configuration.
// iOS: Use Apple Intelligence (recommended)await CapgoLLM.setModel({ path: 'Apple Intelligence'});
// iOS: Use custom MediaPipe model (experimental)await CapgoLLM.setModel({ path: 'Gemma2-2B-IT_multi-prefill-seq_q8_ekv1280', modelType: 'task', maxTokens: 1280});
// Android: Use MediaPipe modelawait CapgoLLM.setModel({ path: '/android_asset/gemma-3-270m-it-int8.task', maxTokens: 2048, topk: 40, temperature: 0.8});| Param | Type | Description |
|---|---|---|
path | string | Model path or “Apple Intelligence” for iOS system |
modelType | string | Optional: Model file type (e.g., “task”, “bin”) |
maxTokens | number | Optional: Maximum tokens the model handles |
topk | number | Optional: Number of tokens considered at each step |
temperature | number | Optional: Randomness in generation (0.0-1.0) |
randomSeed | number | Optional: Random seed for generation |
downloadModel(…)
Section titled “downloadModel(…)”Download a model from URL and save to device storage.
await CapgoLLM.downloadModel({ url: 'https://example.com/gemma-3-270m-it-int8.task', companionUrl: 'https://example.com/gemma-3-270m-it-int8.litertlm', filename: 'gemma-3-270m-it-int8.task'});| Param | Type | Description |
|---|---|---|
url | string | URL to download from |
companionUrl | string | Optional: URL for companion file (.litertlm) |
filename | string | Optional: Filename to save as |
Returns: Promise<{ path: string; companionPath?: string }>
Events
Section titled “Events”textFromAi
Section titled “textFromAi”Fired when AI generates text (streaming response).
CapgoLLM.addListener('textFromAi', (event) => { console.log('AI text:', event.text); console.log('Chat ID:', event.chatId); console.log('Is chunk:', event.isChunk);});Event Data:
text(string) - Incremental text chunk from AIchatId(string) - Chat session IDisChunk(boolean) - Whether this is a complete chunk or partial streaming data
aiFinished
Section titled “aiFinished”Fired when AI completes response.
CapgoLLM.addListener('aiFinished', (event) => { console.log('Completed for chat:', event.chatId);});Event Data:
chatId(string) - Chat session ID
downloadProgress
Section titled “downloadProgress”Fired during model download to report progress.
CapgoLLM.addListener('downloadProgress', (event) => { console.log('Progress:', event.progress, '%'); console.log('Downloaded:', event.downloadedBytes, '/', event.totalBytes);});Event Data:
progress(number) - Percentage of download completed (0-100)downloadedBytes(number) - Bytes downloaded so fartotalBytes(number) - Total bytes to download
readinessChange
Section titled “readinessChange”Fired when the readiness status of the LLM changes.
CapgoLLM.addListener('readinessChange', (event) => { console.log('Readiness changed to:', event.readiness);});Event Data:
readiness(string) - The new readiness status
Complete Example
Section titled “Complete Example”import { CapgoLLM } from '@capgo/capacitor-llm';import { Capacitor } from '@capacitor/core';
class AIService { private chatId: string | null = null; private messageBuffer: string = '';
async initialize() { // Set up model based on platform const platform = Capacitor.getPlatform();
if (platform === 'ios') { // iOS: Use Apple Intelligence (recommended) await CapgoLLM.setModel({ path: 'Apple Intelligence' }); } else { // Android: Use MediaPipe model await CapgoLLM.setModel({ path: '/android_asset/gemma-3-270m-it-int8.task', maxTokens: 2048, topk: 40, temperature: 0.8 }); }
// Wait for model to be ready let isReady = false; while (!isReady) { const { readiness } = await CapgoLLM.getReadiness(); if (readiness === 'ready') { isReady = true; } else if (readiness === 'error') { throw new Error('Failed to load model'); } await new Promise(resolve => setTimeout(resolve, 500)); }
// Create chat session const { id } = await CapgoLLM.createChat(); this.chatId = id;
// Set up event listeners this.setupListeners(); }
private setupListeners() { CapgoLLM.addListener('textFromAi', (event) => { if (event.chatId === this.chatId) { this.messageBuffer += event.text; this.onTextReceived(event.text); } });
CapgoLLM.addListener('aiFinished', (event) => { if (event.chatId === this.chatId) { this.onMessageComplete(this.messageBuffer); this.messageBuffer = ''; } }); }
async sendMessage(message: string) { if (!this.chatId) { throw new Error('Chat not initialized'); }
await CapgoLLM.sendMessage({ chatId: this.chatId, message }); }
onTextReceived(text: string) { // Update UI with streaming text console.log('Received:', text); }
onMessageComplete(fullMessage: string) { // Handle complete message console.log('Complete message:', fullMessage); }}
// Usageconst ai = new AIService();await ai.initialize();await ai.sendMessage('Tell me about AI');Platform Support
Section titled “Platform Support”| Platform | Supported | Requirements |
|---|---|---|
| iOS | ✅ | iOS 13.0+ (26.0+ for Apple Intelligence) |
| Android | ✅ | API 24+ |
| Web | ❌ | Not supported |
Best Practices
Section titled “Best Practices”-
Model Selection: Choose models based on device capabilities
- Use 270M for most mobile devices
- Use 1B for high-end devices with more RAM
- Test performance on target devices
-
Memory Management: Clear chat sessions when done
// Create new chat for new conversationsconst { id } = await CapacitorLLM.createChat(); -
Error Handling: Always check readiness before use
const { readiness } = await CapacitorLLM.getReadiness();if (readiness !== 'ready') {// Handle not ready state} -
Streaming UI: Update UI incrementally with streaming text
- Show text as it arrives via
onAiText - Mark complete with
onAiCompletion
- Show text as it arrives via
-
Model Download: Download models during app setup, not on first use
// During app initializationawait CapacitorLLM.downloadModel({url: 'https://your-cdn.com/model.task',filename: 'model.task'});
Troubleshooting
Section titled “Troubleshooting”Model not loading
Section titled “Model not loading”- Verify model file is in correct location
- Check model format matches platform (.gguf for iOS, .task for Android)
- Ensure sufficient device storage
Poor performance
Section titled “Poor performance”- Try smaller model (270M instead of 1B)
- Close other apps to free memory
- Test on actual device, not simulator
No responses
Section titled “No responses”- Check readiness status is ‘ready’
- Verify event listeners are set up before sending messages
- Check console for errors