theme.colors values as CSS strings, while Chrome only accepts integer arrays. Extension.js resolves the difference at build time, so one manifest.json serves both engines.
One manifest, two color formats
Write hex colors in your manifest and build for any target:[R, G, B, A], where the alpha byte is scaled to a 0 to 1 float and rounded to three decimals. #24283bcc becomes [36, 40, 59, 0.8]. Values that are not hex strings pass through untouched.
Invalid values fail the build
Chrome refuses the whole extension when a theme value has the wrong shape, so Extension.js catches the mistake at compile time instead. On Chromium-family targets, every invalid theme value becomes a compilation error naming the exact field:theme.colors.*entries must be[R, G, B]or[R, G, B, A]arrays, hex strings, or values the converter can produce those from. Channels must be integers from 0 to 255, and the alpha must be numeric.theme.tints.*entries must be[hue, saturation, lightness]arrays of exactly 3 numbers.
Safari targets warn
Safari has no theme surface. When you build forsafari or a webkit-based target and the manifest carries any theme key, the build emits a warning. The field ships unchanged in the output manifest and Safari ignores it.
Static themes skip dev instrumentation
A static theme is a manifest with atheme key and no runtime surface. Extension.js treats a manifest as a static theme when none of these 15 keys is present:
background, content_scripts, action, browser_action, page_action, sidebar_action, side_panel, options_page, options_ui, devtools_page, chrome_url_overrides, sandbox, user_scripts, declarative_net_request, web_accessible_resources
Static themes are exempt from all dev instrumentation. There is nothing to instrument: no background, no pages, no content scripts. More importantly, a theme is validated against the theme schema, which forbids extra top-level keys, and addons.mozilla.org hard-errors on each one. Injecting dev-only keys would make the artifact stop being a valid theme.
The decision reads your manifest.json from disk, not the in-flight build output. By the time dev patches land, the compiled manifest already carries injected keys and no longer looks like a theme.
Next steps
- Target one engine per field with Browser-specific manifest fields.
- Build per-target artifacts with Multi-platform builds.

