importChromiumAIfrom'simple-chromium-ai';// Initialize onceconstresult=awaitChromiumAI.initialize("You are a helpful assistant");letai;if(result.type==='initialized'){// Model already availableai=result.instance;}else{// Need to trigger download from user interaction (e.g., button click)document.getElementById('download-button').onclick=async()=>{ai=awaitresult.trigger();};}// Simple promptconstresponse=awaitChromiumAI.prompt(ai,"Write a haiku");// Or use the Safe API for error handlingconstsafeResponse=awaitChromiumAI.Safe.prompt(ai,"Write a haiku");if(safeResponse.isOk()){console.log(safeResponse.value);}
Chrome 138+ or supported Chromium browser
Enable "Prompt API for Gemini Nano" in chrome://flags
Update "Optimization Guide On Device Model" in chrome://components
constresult=awaitChromiumAI.initialize(systemPrompt?: string,onDownloadProgress?: (progress: number)=>void);// Result is a tagged unionif(result.type==='initialized'){constai=result.instance;}else{// result.type === 'needs-download'constai=awaitresult.trigger();// Call from user gesture}
Important: Chrome requires user interaction to download the AI model. When the model needs to be downloaded, initialize returns an object with type: 'needs-download' and a trigger function that you must call from a user gesture (like a button click).
constresponse=awaitChromiumAI.prompt(ai,"Your prompt",timeout?: number
);
// Create reusable sessionconstsession=awaitChromiumAI.createSession(ai);constresponse1=awaitsession.prompt("Hello");constresponse2=awaitsession.prompt("Follow up");// Maintains contextsession.destroy();// Override the instance's system prompt for this sessionconstcustomSession=awaitChromiumAI.createSession(ai,{initialPrompts: [{role: 'system',content: 'You are a pirate'}]});// Or use withSession for automatic cleanupconstresult=awaitChromiumAI.withSession(ai,async(session)=>{returnawaitsession.prompt("Hello");});
Every function has a Safe variant that returns Result types instead of throwing:
import{ChromiumAI}from'simple-chromium-ai';constresult=awaitChromiumAI.Safe.initialize("You are helpful");if(result.isErr()){console.error("Failed:",result.error.message);return;}constvalue=result.value;if(value.type==='initialized'){constai=value.instance;constresponse=awaitChromiumAI.Safe.prompt(ai,"Hello");}else{// Need user interaction to downloadbutton.onclick=async()=>{constaiResult=awaitvalue.trigger();if(aiResult.isOk()){constai=aiResult.value;constresponse=awaitChromiumAI.Safe.prompt(ai,"Hello");}};}
The wrapper enforces proper initialization through TypeScript:
// ❌ Won't compile - need AI instanceawaitChromiumAI.prompt("Hello");// ✅ Correct usageconstresult=awaitChromiumAI.initialize("You are helpful");constai=result.type==='initialized'
? result.instance
: awaitresult.trigger();awaitChromiumAI.prompt(ai,"Hello");
This wrapper prioritizes simplicity over flexibility. You cannot:
Create reusable session. Options can override system prompt
LanguageModel
withSession(ai, callback)
Execute with temporary session
T
checkTokenUsage(ai, prompt)
Check if prompt fits in context
TokenUsageInfo
Each function has a Safe.* variant that returns Result<T, Error> instead of throwing.
constresult=awaitChromiumAI.initialize("You are a friendly assistant");constai=result.type==='initialized'
? result.instance
: awaitresult.trigger();// Call from user gestureconstresponse=awaitChromiumAI.prompt(ai,"Tell me a joke");
constresult=awaitChromiumAI.initialize("You are helpful",(progress)=>console.log(`Downloading: ${progress}%`));if(result.type==='needs-download'){// Trigger download from user interactiondocument.getElementById('download-button').onclick=async()=>{constai=awaitresult.trigger();// Use ai...};}
// Show/hide button based on model availabilityconstbutton=document.getElementById('download-button');try{constresult=awaitChromiumAI.initialize("You are helpful");if(result.type==='initialized'){// Model is ready - hide download buttonbutton.style.display='none';constai=result.instance;// Use the AIconstresponse=awaitChromiumAI.prompt(ai,"Hello!");}else{// Show button - download neededbutton.style.display='block';button.textContent='Download AI Model';button.onclick=async()=>{button.disabled=true;button.textContent='Downloading...';try{constai=awaitresult.trigger();button.style.display='none';// Use the AIconstresponse=awaitChromiumAI.prompt(ai,"Hello!");}catch(error){button.disabled=false;button.textContent='Retry Download';console.error('Download failed:',error);}};}}catch(error){console.error('Initialization failed:',error);}
constusage=awaitChromiumAI.checkTokenUsage(ai,longText);if(!usage.willFit){// Use shorter promptconstresponse=awaitChromiumAI.prompt(ai,"Summarize briefly");}
Structured Output with Response Constraints
// Define JSON schema for the responseconstschema={type: "object",properties: {sentiment: {type: "string",enum: ["positive","negative","neutral"]},confidence: {type: "number",minimum: 0,maximum: 1},keywords: {type: "array",items: {type: "string"},maxItems: 5}},required: ["sentiment","confidence","keywords"]};// Create session with response constraintconstresponse=awaitChromiumAI.prompt(ai,"Analyze the sentiment of this text: 'I love this new feature!'",undefined,// no timeout{responseConstraint: schema});// Response will be valid JSON matching the schemaconstresult=JSON.parse(response);console.log(result);// { sentiment: "positive", confidence: 0.95, keywords: ["love", "new", "feature"] }
Cancellable Prompts with AbortController
// Create an AbortController to cancel long-running promptsconstcontroller=newAbortController();// Set up a cancel buttonconstcancelButton=document.getElementById('cancel');cancelButton.onclick=()=>controller.abort();try{// Pass the abort signal to the promptconstresponse=awaitChromiumAI.prompt(ai,"Write a detailed analysis of quantum computing...",undefined,// no timeout{signal: controller.signal}// abort signal);console.log(response);}catch(error){if(error.name==='AbortError'){console.log('Prompt was cancelled by user');}else{console.error('Error:',error.message);}}