sch39

Tutorial on Running Web Char Companion: A Virtual Character That Lives on Top of Web Pages

Oct 2026 · 8 min read

A step-by-step guide to running the Web Char Companion browser extension, from prerequisites, installation, and configuration, to understanding its code architecture for beginner to intermediate developers.

Imagine a tiny virtual character that walks around, reads headings, sits on buttons, and stares at images on the web page you're currently viewing. Web Char Companion is a Manifest V3 browser extension that brings that idea to life — and the good news is, this project has no build step and no dependencies, making it perfect as learning material for beginner to intermediate developers. This article will guide you from scratch: setting up prerequisites, installing, configuring, running, trying it out, and understanding the code structure behind it.

1. Prerequisites

Since this project is pure HTML, CSS, and JavaScript, you don't need to install Node.js, npm, or any bundler. All you need is a Chromium-based browser and Git (optional, only if you want to clone the repo).

Requirement

Version / Notes

Browser

Google Chrome, Microsoft Edge, or another Chromium browser that supports Manifest V3 (Chrome 88+, Edge 88+)

Git

Latest version (optional, only for cloning the repository)

Code editor

VS Code, Sublime, or any editor

Operating system

Windows, macOS, or Linux — no special system dependencies

This extension is not available on the Chrome Web Store, so installation is only through "Load unpacked" mode. A .crx file dropped into chrome://extensions will be blocked by Chrome.

2. Installing Dependencies

This project has no npm or Python dependencies. "Installation" here means getting the source code onto your computer. There are two ways:

bash
git clone https://github.com/Sch39/web-char-companion.git
cd web-char-companion

Option B — Download the latest release

Go to the Releases page on GitHub, download the web-char-companion-<version>.zip file, then extract it to a permanent folder. Example using the terminal:

bash
unzip web-char-companion-1.0.0.zip -d web-char-companion
cd web-char-companion

Make sure the extracted folder contains the manifest.json file. Verify with:

bash
ls manifest.json

Important: don't move this folder after loading it. Chrome loads the unpacked extension from that path every time the browser starts, and the extension will disappear if the folder is moved.

3. Configuration

Web Char Companion doesn't use a .env file. All settings live in two places: the CONFIG object inside the code and the extension options page in the browser.

a. Changing configuration in the code

Open the configuration file (usually config.js or the top part of the main script) and find the CONFIG object. Some values that are commonly changed:

javascript
const CONFIG = {
  // Maximum duration (seconds) for a video to be considered
  // a decorative background, not something that must be watched.
  // Set to 0 so the character reacts to ALL playing videos.
  decorativeMaxDurationSec: 30,

  // How often the character picks a new target (ms)
  retargetIntervalMs: 5000,

  // Enable/disable the note reaction when typing
  reactToTyping: true,
};

b. Configuration via the Options page

Click the extension icon in the toolbar, then select Options. There you can configure:

  • Per-site control — choose Always on, Always off, or Automatic for each site.

  • Keyword list — a list of URL keywords (e.g., login, bank, checkout) that automatically hide the character.

  • Per-tab character — assign a special character to a specific tab without disturbing other tabs.

  • Pause — temporarily disable the character.

  • Alarm — add a reminder with a system notification and Snooze / Dismiss buttons.

All these settings are stored using chrome.storage and apply across tabs.

4. How to Run the Project

Since this is an unpacked extension, "running" means loading it into the browser. Follow these steps:

  1. Open a new tab and go to chrome://extensions (or edge://extensions for Edge).

  2. Enable Developer mode in the top right corner.

  3. Click the Load unpacked button.

  4. Select the folder containing manifest.json (the result of your clone/extract).

  5. The extension will appear in the list with the name Web Char Companion.

  6. Open any site, for example https://developer.mozilla.org — the character will appear and start walking around.

To reload after changing code:

  1. Click the reload icon (⟳) on the extension card at chrome://extensions.

  2. Refresh the tab you currently have open.

To view logs and debug:

bash
# Open DevTools on the web page tab: F12 or Ctrl+Shift+I
# For the background service worker:
# chrome://extensions -> Web Char Companion -> "service worker"

5. Usage Examples

Example 1 — Watching the character react on a documentation page

This is the simplest scenario to verify that the extension works.

  1. Open https://developer.mozilla.org/en-US/docs/Web/JavaScript.

  2. Notice the character appear in the corner of the screen and start walking.

  3. Scroll down — the character will pick a new element: stop at a heading, look at an image, or sit on a button.

  4. Click the character to trigger a quick reaction, or drag it to another position — it will stay there.

  5. Leave the tab idle for a few seconds, and the character will doze off.

Example 2 — Setting alarms and notifications

Alarms are useful for testing the chrome.alarms and chrome.notifications integration.

  1. Click the extension icon → Options → Alarm.

  2. Add an alarm, for example 14:30:00.

  3. Switch to another tab (leave the tab with the web page in the background).

  4. When the time comes, the character appears with a speech bubble, plays the alarm animation, and makes a sound.

  5. A system notification will appear with Snooze and Dismiss buttons, so you still receive the reminder even when the browser is covered by another application.

The alarm sound is played by the extension, not by the web page. This means the alarm still sounds even if the tab is muted, has never been clicked, or is in the background. You can replace the sound file with your own audio file.

Example 3 — Adding per-site rules

javascript
// Via the Options page -> Per-site control, or via the DevTools console
// on the options page (for experimentation):
chrome.storage.sync.set({
  siteRules: {
    'example.com': 'off',
    'docs.github.com': 'on',
  },
  hideKeywords: ['login', 'bank', 'checkout', 'password'],
});

6. Architecture and Code Structure

Understanding the project structure will make it easier for you to modify the character's behavior. Broadly speaking, the code is divided into three areas: the manifest, the content script (character logic on the page), and the service worker (background logic such as alarms).

Folder structure (abridged)

text
web-char-companion/
├── manifest.json          # Extension declaration (MV3)
├── content/
│   ├── content.js         # Main logic: overlay, walking, target scoring
│   ├── companion.css      # Character styling inside the Shadow DOM
│   └── player.js          # Character animation
├── background/
│   └── service-worker.js  # Alarms, notifications, cross-tab sync
├── options/
│   ├── options.html       # Settings page
│   ├── options.css
│   └── options.js
├── assets/
│   ├── sprites/           # Character sprite sheet
│   └── sounds/            # Alarm sounds (replaceable)
└── demo/
    └── demo.gif / demo.mp4

Main components

  • Content script — injected into every page. Creates a transparent overlay inside the Shadow DOM so it doesn't alter the page layout and doesn't interfere with clicks (by default pointer-events: none, except on the character element).

  • Target scoring — the content script scans visible elements (headings, images, videos, buttons, paragraphs), assigns a score based on type and visibility, then picks a target with a bit of randomness so it feels natural.

  • Player / animation — manages the sprite sheet and animation states such as idle, walk, sit, watch, and alarm.

  • Service worker — handles chrome.alarms and chrome.notifications, and syncs the alarm list across tabs. Only the active tab shows the speech bubble; other tabs still receive system notifications.

  • Options page — the UI for per-site control, keyword list, and other settings stored in chrome.storage.

Workflow (flow)

  1. Injection: When the user opens a page, Chrome injects content.js. If the URL matches the keyword list or a per-site = off rule, the character is not shown.

  2. Overlay setup: The content script creates a host element and attaches a Shadow DOM to isolate styles.

  3. Scanning & scoring: Periodically, the script scans visible DOM elements and computes a score for each element. The target with the highest score (with a little random noise) is selected.

  4. Action: The character walks to the target and performs an action based on the element type (for example reading a heading, staring at an image, or sitting on a button).

  5. User interaction: A click triggers a quick reaction; a drag moves the character and its position is saved per tab so a refresh doesn't return it to its initial position.

  6. Alarm: The service worker triggers the alarm; the content script shows a bubble in the active tab, and chrome.notifications shows a system notification for other tabs.

  7. Video detection inside iframes: A small script is injected into each frame to monitor the is playing status and report it to the top frame — without reading the iframe content.

Privacy: the character only reads the structure of the page (what elements exist and where), not the text you type, the clipboard, or form values. For sensitive fields (password, credit card, OTP), its reaction is different — the character moves away, and the field value is never read.

Debugging Tips and Best Practices

  • Open DevTools on the page tab to see content script logs. For the service worker, click the service worker link on the extension card at chrome://extensions.

  • Test on various pages (documentation, marketplaces, videos) to see the variety of target scoring.

  • Use the Shadow DOM when adding new styles so the page's CSS doesn't leak in, and vice versa.

  • Respect prefers-reduced-motion — this extension already honors it; don't disable it without reason.

  • Always reload the extension at chrome://extensions after changing code, then refresh the tab.

Conclusion

Web Char Companion is a great example of a Manifest V3 project with no build step that combines a content script, Shadow DOM, service worker, and options page into one compact whole. By following the installation and configuration steps above, you can immediately see the virtual character in action, change its behavior via CONFIG, and start experimenting with the target scoring logic and animations. Give it a try — and let that little character accompany your browsing activities!