Build for Caspian

Caspian runs Chrome-format extensions in its own runtime, on Windows and macOS. If you have written a Chrome extension, you have written a Caspian extension. If you haven't, it takes an afternoon.

How extensions run in Caspian

Chrome's extension system lives inside Chromium and is not exposed by the engine Caspian is built on, so Caspian carries its own runtime. Your code sees the same surface it would in Chrome: a chrome (and browser) object in every context, content scripts in an isolated world with DOM access, a background service worker that stays up, a toolbar button with a popup and a badge, an options page, storage, messaging and ports, keyboard commands, context-menu entries, notifications and alarms. Where the engine needs help, Keel — Caspian's own build of the engine — supplies the hook: extension pages fetch their host permissions without CORS exactly as in Chrome.

Anything Caspian doesn't implement answers instead of throwing: unknown functions resolve to undefined, unknown on* members are events nobody fires. Extensions that touch an API we lack degrade instead of dying.

Thirty seconds to a running extension

manifest.jsonjson
{
  "manifest_version": 3,
  "name": "Hello Caspian",
  "version": "1.0",
  "action": { "default_title": "Hello" },
  "background": { "service_worker": "bg.js" }
}
bg.jsjs
chrome.action.onClicked.addListener((tab) => {
  chrome.caspian.status("Hello from " + new URL(tab.url).host);   // Caspian's status line
});

Open caspian:extensions, choose Load unpacked…, pick the folder. Pin it, click the button. Reload after each change with the card's Reload; background errors show on the card.

Already on the Chrome Web Store?
It works today: open your listing in Caspian and the button reads Add to Caspian. Listing on the Caspian Extension Store gets you a verified badge and a place in Caspian's own catalogue — see Store & verification.

Telling Caspian apart

Caspian presents as Chrome to sites (user agent and client hints carry a Caspian brand next to Chromium). Inside an extension, chrome.caspian exists only in Caspian, and chrome.runtime.getURL("") starts with caspian-ext:// rather than chrome-extension://.

const inCaspian = typeof chrome !== "undefined" && !!chrome.caspian;
const brand = navigator.userAgentData?.brands.some((b) => b.brand === "Caspian");

The engine, if you go deeper

Caspian's engine is Keel: Qt WebEngine (Chromium) built from source with Caspian's patches — frames paced to the display's refresh rate, H.264/AAC/HEVC on every platform, and the CORS hook for extensions. The patches and build scripts live in the repository under keel/. Keel is what ships on both platforms from 0.1.5.