Implementation:Mlc ai Web llm Manifest V3 Configuration
Overview
Pattern documentation for the required manifest.json structure when building Chrome extensions with @mlc-ai/web-llm. This implementation details the specific Manifest V3 fields, Content Security Policy directives, and permission declarations needed to enable in-browser LLM inference via WebGPU and WASM within the Chrome Extension security sandbox.
Description
The web-llm Chrome extension manifest follows a specific pattern that addresses three Chrome Extension security constraints:
- WASM execution requires
wasm-unsafe-evalin the Content Security Policy - ES module imports require
"type": "module"on the service worker registration - Model weight downloads require whitelisted CDN domains in the
connect-srcCSP directive
The repository provides two reference manifests: one for the service-worker-based architecture (examples/chrome-extension-webgpu-service-worker/src/manifest.json) and one for the popup-only architecture (examples/chrome-extension/src/manifest.json). Both share the same CSP pattern but differ in their background script configuration and permissions.
Code Reference
Source: examples/chrome-extension-webgpu-service-worker/src/manifest.json (full file)
{
"manifest_version": 3,
"name": "MLCBot",
"version": "0.1.0",
"description": "Chat with your browser",
"icons": {
"16": "icons/icon-16.png",
"32": "icons/icon-32.png",
"64": "icons/icon-64.png",
"128": "icons/icon-128.png"
},
"content_security_policy": {
"extension_pages": "style-src-elem 'self' https://cdnjs.cloudflare.com; font-src 'self' https://cdnjs.cloudflare.com; script-src 'self' 'wasm-unsafe-eval'; default-src 'self' data:; connect-src 'self' data: http://localhost:8000 https://huggingface.co https://cdn-lfs.huggingface.co https://cdn-lfs-us-1.huggingface.co https://raw.githubusercontent.com https://cdn-lfs-us-1.hf.co https://cas-bridge.xethub.hf.co"
},
"action": {
"default_title": "MLCBot",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"background": {
"service_worker": "background.ts",
"type": "module"
},
"permissions": ["storage", "tabs", "webNavigation"]
}
I/O Contract
Input: The manifest.json file must be present at the root of the extension source directory. It is consumed by Chrome at extension install/load time.
Output: Chrome registers the extension with the declared capabilities, installs the service worker, and injects content scripts.
Required CSP Directives
| Directive | Value | Reason |
|---|---|---|
script-src |
'self' 'wasm-unsafe-eval' |
Allows loading extension scripts and compiling WASM modules (TVM runtime) |
connect-src |
Hugging Face domains (see below) | Allows fetching model weights from Hugging Face CDN |
default-src |
'self' data: |
Base policy; allows data URIs for inline resources |
Hugging Face CDN domains that must appear in connect-src:
https://huggingface.co- Main Hugging Face domainhttps://cdn-lfs.huggingface.co- Git LFS storage for model weightshttps://cdn-lfs-us-1.huggingface.co- US region LFS mirrorhttps://raw.githubusercontent.com- Raw GitHub content for config fileshttps://cdn-lfs-us-1.hf.co- Shortened HF domain for US region LFShttps://cas-bridge.xethub.hf.co- XetHub CAS bridge for large file storage
Background Service Worker Fields
| Field | Value | Constraint |
|---|---|---|
background.service_worker |
Path to background script (e.g. "background.ts") |
Must point to the script that creates ServiceWorkerMLCEngineHandler
|
background.type |
"module" |
Required. Without this, import statements in the background script will fail with a SyntaxError
|
Permissions
| Permission | Required? | Purpose |
|---|---|---|
storage |
Yes | Used for caching model metadata |
tabs |
Only for page content access | Needed for chrome.tabs.connect() to communicate with content scripts
|
webNavigation |
Only for page content access | Needed to detect page navigation events |
Usage Examples
Minimal manifest (inference only, no page content access):
{
"manifest_version": 3,
"name": "SimpleLLM",
"version": "1.0.0",
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; default-src 'self' data:; connect-src 'self' data: https://huggingface.co https://cdn-lfs.huggingface.co https://cdn-lfs-us-1.huggingface.co https://raw.githubusercontent.com https://cdn-lfs-us-1.hf.co https://cas-bridge.xethub.hf.co"
},
"action": {
"default_popup": "popup.html"
},
"background": {
"service_worker": "background.js",
"type": "module"
},
"permissions": ["storage"]
}
Building with Parcel (the recommended bundler for web-llm Chrome extensions):
{
"scripts": {
"build": "parcel build src/manifest.json --config @parcel/config-webextension"
},
"devDependencies": {
"@parcel/config-webextension": "^2.9.3",
"@types/chrome": "^0.0.242",
"parcel": "^2.9.3"
},
"dependencies": {
"@mlc-ai/web-llm": "^0.2.80"
}
}
The Parcel web extension config understands manifest.json as an entry point. It resolves background.ts, popup.ts, and content.js from the manifest, bundles them, and produces a ready-to-load extension in the dist/ directory.
Loading the built extension in Chrome:
- Run
npm run buildin the extension project directory - Open
chrome://extensionsin Chrome - Enable "Developer mode"
- Click "Load unpacked" and select the
dist/directory
External Dependencies
| Dependency | Version | Purpose |
|---|---|---|
| Chrome Extensions API | Manifest V3 | Extension platform; Chrome 88+ required for service workers |
@mlc-ai/web-llm |
^0.2.80 |
LLM inference library |
@parcel/config-webextension |
^2.9.3 |
Build tooling for Chrome extension bundling |
@types/chrome |
^0.0.242 |
TypeScript type definitions for Chrome API |
Related Pages
- Principle:Mlc_ai_Web_llm_Chrome_Extension_Manifest
- Mlc_ai_Web_llm_Service_Worker_MLC_Engine_Handler - Background script implementation that the manifest registers as the service worker
- Mlc_ai_Web_llm_Create_Service_Worker_MLC_Engine - Popup-side engine factory that connects to the registered service worker
- Mlc_ai_Web_llm_Chrome_Tabs_Connect - Content script implementation declared in the manifest
- Environment:Mlc_ai_Web_llm_Chrome_Extension_Manifest_V3