Component Extension
How Vibe is built into Chromium as a component extension.
Overview
Unlike regular Chrome extensions, component extensions are:
- Built into the browser binary
- Loaded automatically at startup
- Given special privileges
- Not visible in
chrome://extensions
Registration
Component extensions are registered in C++ code:
// chrome/browser/extensions/component_loader.cc
Add(IDR_VIBE_MANIFEST,
base::FilePath(FILE_PATH_LITERAL("vibe")));
Build Integration
1. ninja calls build.js
↓
2. Scripts bundled: content.js, background.js, sidepanel.js
↓
3. Files declared in component_extension_resources.grd
↓
4. Packed into component_extension_resources.pak
↓
5. Loaded at browser startup
Extension ID
The permanent extension ID is derived from a private key:
ID: opocihnfjcgcjecjhjjgifkbkgeeoonh
This ID is hard-coded in C++ for privilege checks.
Special Privileges
Component extensions can bypass restrictions:
Side Panel API
// Bypass user gesture requirement
// sidePanel.open() can be called programmatically
Toolbar Integration
- Automatically pinned to toolbar
- Text label next to icon
- Custom position handling
Manifest Configuration
{
"side_panel": {
"default_path": "chat.html"
},
"chrome_url_overrides": {
"newtab": "chat.html"
}
}
Settings Integration
Users configure Vibe at chrome://settings/ai/vibeConfig:
- Provider selection (OpenAI, Gemini)
- API key entry (encrypted storage)
- Model selection
- Temperature, timeout settings
Settings are stored in browser preferences and accessed via chrome.settingsPrivate API.
Building
# Full Chromium build (8+ hours)
ninja -C out/Debug chrome
Do NOT use node esbuild.js - it creates an incorrect dist folder.
Testing
Component extensions require different testing approaches:
# Launch Chromium (extension loads automatically)
./out/Debug/Chromium.app/Contents/MacOS/Chromium
# Extension is available immediately on new tab
# No --load-extension flag needed