@omega.js/extension
v0.56.0
Published
OMEGA extension framework — build, test, and package Chrome/Firefox extensions (MV3)
Maintainers
Readme
🦄 Features
- Build for any browser: Chrome, Firefox, Edge, Opera, Brave
- Component architecture: seven contexts (background / popup / options / sidepanel / content / pages / offscreen) each with view + styles + script
- One ready-made
omegaper context:import omega from '@omega.js/extension/popup'; await omega.initialize();, with the cross-browser API wrapper, the logger and the messenger on every context, and@omega.js/clienton the four page contexts - Cross-context auth sync: sign-in in one tab is reflected in all open contexts (no
chrome.storageneeded) - Vert (ad) units with zero JS: drop
<div data-omega-vert></div>into a popup/options/sidepanel/page view — auto-bound to the shared OMEGA verts module (house/company inventory only, no AdSense). See docs/extension/verts.md - Affiliate redirects: a visit to a partner site (Amazon, Rakuten, NordVPN, …) redirects once per 24h to an affiliate URL — default-on,
?affiliatizerStatus=blockto stop it. The partner map is a fixed framework constant carrying the framework author's referral codes, not per-brand config. See docs/extension/affiliatizer.md - Auto-translation to the languages in
translation.languages(omega.json5) on every build — only missing keys hit the provider - Four-layer test framework: build / background / view / boot — real Chromium, real MV3 service worker, real consumer extensions
- Multi-browser packaging + auto-publish to Chrome / Firefox / Edge stores from one command
- Theme system: Bootstrap 5 + Classy (custom design system), or roll your own
- SCSS load paths:
@use 'omega-extension'/@use 'theme'Just Work — no relative-path hell
🚀 Getting started
npm i @omega.js/extensionin your project (or start from an empty directory — the first verb scaffolds everything).- Set up + run:
npm install npm start - Open Chrome and navigate to
chrome://extensions. - Enable Developer mode.
- Click Load unpacked and select the
packaged/chrome/rawfolder in your project. - Your extension is loaded and live-reloads on source changes.
📦 Sync with the template
Every verb (npm start, npx omega build, npx omega test, npx omega deploy) refreshes the framework defaults first. Files you've edited are preserved; only missing or framework-owned files update.
🧪 Testing
@omega.js/extension ships a built-in four-layer test framework. Write tests under test/<layer>/*.test.js and run with:
npx omega test # YOUR project's tests only (C5 scoping — docs/shared/testing.md)
npx omega test framework: # the framework's own suite (aliases: omega:, mgr:, extension:)
npx omega test full: # both sources
npx omega test --layer=build # build layer only (plain Node, fast; orthogonal to scoping)
npx omega test --layer=boot # real-Chromium end-to-end test
npx omega test --extended # also run extended suites against REAL external services (Firebase, etc.)Tests run against the real harness: a real MV3 service worker, a real Chromium tab, the real packaged extension. Never mock (chrome, omega, contexts are all real); only pure, I/O-free functions are called directly. Real external APIs are gated behind extended mode: --extended or the shared, unprefixed TEST_EXTENDED_MODE=true env var (skipped in-source otherwise, never mocked).
All CLI output also lands in logs/ (ANSI-stripped, truncated each run) — test.log from npx omega test, dev.log from npm start, build.log from npm run build. Details: docs/extension/logging.md.
Test files use Jest-compatible matchers:
// test/build/manifest.test.js
const build = require('@omega.js/extension/build');
const { defineCases } = require('@omega.js/extension/test');
module.exports = defineCases({
layer: 'build',
description: 'manifest is valid MV3',
run: (ctx) => {
const m = build.getManifest();
ctx.expect(m.manifest_version).toBe(3);
ctx.expect(m.permissions).toContain('storage');
},
});Full guide: docs/extension/test-framework.md. End-to-end "did my packaged extension actually boot in Chrome?" tests: docs/extension/test-boot-layer.md.
🌐 Auto-translation
When you run npm run build, @omega.js/extension auto-translates config/messages.json to the languages set in translation.languages (omega.json5), via the shared devkit translation engine (Claude CLI by default). Translation is off until translation.languages is set.
Only missing translations are generated — existing translations live in the committed translations/ cache and are preserved. Full guide: docs/extension/translations.md.
🎨 Design tokens (C4)
The cross-target --omega-* token contract (defined once in
@omega.js/web's core/css/tokens/_index.scss) is vendored into
dist/assets/css/tokens/ at prepare (package.json omega.vendorAssets)
and emitted by the omega-extension entry BEFORE the theme — theme rules
override at equal specificity, and component scss can read
var(--omega-*) directly. First consumer: body { accent-color:
var(--omega-accent) }. The full component migration onto tokens lands
with the C3/D10 skin.
🌎 Publishing your extension
Manual upload
npx omega build # `npm run build` is the same pipeline — the script is a thin alias of the verbUpload the .zip files under packaged/<browser>/ to each browser's extension store.
Firefox needs an add-on id. Declare none and the build derives one from your brand (
extension@<your brand host>); declarebrowser_specific_settings.gecko.idinsrc/manifest.jsonbefore your first publish, because the id has to stay the same for every release. The firefox artifact also gets its own translation of the chrome-only side panel keys (side_panel→sidebar_action), so the panel actually works.
Automatic publishing
OMEGA_IS_PUBLISH=true npm run buildEach store's own listing ID is public, so it lives in config/omega.json5
beside that listing's url:
targets: {
extension: {
type: 'extension',
listings: {
chrome: { id: '...' },
firefox: { id: '[email protected]' },
edge: { id: '...' },
},
},
},Add the store API credentials to your .env:
# Chrome Web Store
CHROME_CLIENT_ID="..."
CHROME_CLIENT_SECRET="..."
CHROME_REFRESH_TOKEN="..."
# Firefox Add-ons
FIREFOX_API_KEY="..."
FIREFOX_API_SECRET="..."
# Microsoft Edge Add-ons
EDGE_CLIENT_ID="..."
EDGE_API_KEY="..."Only stores with configured credentials get published to. Full guide: docs/extension/publishing.md.
🔐 Authentication
@omega.js/extension provides built-in cross-context authentication that syncs across all extension contexts (popup, options, sidepanel, pages, background) without using chrome.storage.
Background's omega.auth is the source of truth. Auth syncs over omega.messenger: sign-in / sign-out events propagate across all open contexts, and new contexts handshake with background on load, pushing their account document so background's omega.auth.user is the same User.
Setup
- Set
brand.urlinconfig/omega.json5(background.js watches that host for the /token redirect) - Add
tabspermission tosrc/manifest.json
Auth button classes
Add these CSS classes to HTML elements for declarative auth UI:
| Class | Action |
|---|---|
| .omega-signin | Opens /token page on your website |
| .omega-signout | Signs out via @omega.js/client (broadcasts to all contexts) |
| .omega-account | Opens /account page on your website |
<button class="btn omega-signin" data-omega-bind="@show !auth.user.authenticated">Sign In</button>
<div data-omega-bind="@show auth.user.authenticated" hidden>
<img data-omega-bind="@attr src auth.user.profile.photoURL">
<span data-omega-bind="@text auth.user.profile.displayName">User</span>
<button class="omega-account">Account</button>
<button class="omega-signout">Sign Out</button>
</div>Full guide: docs/extension/auth.md.
🔒 Supply-chain security
All npm install calls in @omega.js/extension CLI commands (the peer-dependency step every verb runs) route through Socket Firewall when installed, blocking confirmed malware at the network level before packages reach disk. Falls back to plain npm if sfw isn't available. Consumer CI workflows (publish.yml default) install sfw globally and run sfw npm ci.
📚 Documentation
In-depth docs for every subsystem live in docs/extension/; the architecture overview is the framework guide, docs/extension/index.md in the omega monorepo.
🧰 Sister projects
- @omega.js/desktop: same patterns, but for Electron desktop apps
- @omega.js/web: the Eleventy web framework
- @omega.js/backend: the Firebase Functions backend framework
📜 License
Elastic License 2.0. The source is free to use and modify; a license key unlocks payments in production deploys and removes the attribution (local dev and test payments are always free); and you may not offer @omega.js/extension to third parties as a hosted or managed service.
