Skip to main content

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:

  1. Provider selection (OpenAI, Gemini)
  2. API key entry (encrypted storage)
  3. Model selection
  4. 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