These mostly single-engine APIs are progressive enhancements: always feature-detect. Chrome 1 's built-in AI APIs run Gemini 1 Nano and smaller expert models on the device, with no API key or per-token cost, and text never leaves the machine. The model downloads on first use and needs a desktop OS (Windows 10/11, macOS 13+, Linux, Chromebook Plus), 22 GB of free disk, and a GPU with over 4 GB of VRAM or 16 GB of RAM and 4 cores.
| API | What it does | Status (September 2026) |
|---|---|---|
| Prompt API (LanguageModel) | Prompts with JSON-schema output | Stable in Chrome 148 desktop |
| Summarizer, Translator, Language Detector | Task-specific on-device models | Stable in Chrome 138 desktop |
| Writer, Rewriter, Proofreader | Draft, rephrase and correct text | Developer trial (behind a flag) |
| WebNN (navigator.ml) | Neural nets on CPU, GPU, NPU | Origin trial since Chrome 146 |
| Digital Credentials | ID documents from wallet apps | Chrome 141, Safari 26 10 |
| Web Share (navigator.share()) | The OS share sheet | Chrome, Safari; Firefox 555 flag |
| EyeDropper | Pick a color anywhere on screen | Chromium 4,389 desktop only (95+) |
| Isolated Web Apps | Signed, installable app bundles | Managed ChromeOS devices only |
Each AI API follows one pattern: availability() returns unavailable, downloadable, downloading or available, and create(), called from a user gesture, reports download progress and returns an object with batch and streaming methods.
<article>Long product reviews ...</article>
<button id="tldr">Summarize</button>
<script type="module">
const options = { type: 'tldr', length: 'short', outputLanguage: 'en' };
const state = 'Summarizer' in self ? await Summarizer.availability(options) : 'unsupported';
console.log('Summarizer', state);
const pair = { sourceLanguage: 'en', targetLanguage: 'fr' };
console.log('Translator', await self.Translator?.availability(pair));
tldr.addEventListener('click', async () => { // create() needs user activation
if (state === 'unavailable' || state === 'unsupported') return fetch('/api/summarize');
const summarizer = await Summarizer.create({ ...options, monitor: (m) =>
m.addEventListener('downloadprogress', (e) => console.log(`model ${e.loaded * 100}%`)) });
console.log(await summarizer.summarize(document.querySelector('article').innerText));
});
</script>Summarizer unavailable Translator downloadable
Headless Chrome 152 has the constructors but no model service. The Prompt API is analogous: LanguageModel.create(), then session.prompt(text, { responseConstraint: jsonSchema }); its sampling controls are in a separate origin trial.
The rest need a user gesture. new EyeDropper().open() resolves to { sRGBHex }. navigator.share({ title, url }) needs HTTPS and transient activation; keep a copy-link fallback. navigator.credentials.get({ digital: { requests } }) asks a wallet for an ID over OpenID4VP or ISO 18013-7 Annex C. Isolated Web Apps are signed Web Bundles with isolated-app:// origins that unlock Direct Sockets and Controlled Frame, installed by admins on managed Chromebooks.