Skip to content

Extensions

Maho Browser supports desktop Chrome-compatible extensions using the Manifest V3 standard (loaded via unpacked directories or CRX files). Manifest V2 is deprecated and not supported. Mobile shells (iOS and Android) do not support extensions.

[!NOTE] Extension compatibility depends on standard Chromium extension APIs. Third-party ad-blocking extensions (such as uBlock Origin Lite) operate using Declarative Net Request (DNR) in Extension Mode. Content Blocking Mode in Settings controls Maho’s native engine independently of installed extensions.

On desktop, extensions can be loaded from unpacked local directories containing a valid Manifest V3 manifest.json or imported from local CRX files.

When Maho loads an extension, it validates the manifest and activates supported background service workers and content scripts.

Maho supports the following Manifest V3 fields.

FieldRequiredNotes
manifest_versionYesMust be 3
nameYesString
versionYesString in semver format
descriptionNoString
iconsNoIcon map, commonly 16, 48, and 128
actionNoBrowser toolbar button configuration
backgroundNoService worker configuration
content_scriptsNoScript and style injection rules
permissionsNoExtension permissions
host_permissionsNoURL pattern permissions
web_accessible_resourcesNoResources exposed to pages
content_security_policyNoExtension page CSP
options_pageNoExtension options page
options_uiNoOptions UI configuration
devtools_pageNoDevTools integration page

Must be set to 3. Maho only supports Manifest V3 extensions.

The extension name. This field is required and must be a string.

The extension version in semver format. Maho expects a standard version string.

A short human-readable summary of the extension.

Icon paths keyed by size. Common sizes include:

  • 16
  • 48
  • 128

Defines the browser toolbar button. Supported properties include:

  • default_popup
  • default_icon
  • default_title

Declares the background service worker. Maho supports:

  • service_worker
  • type: "module"

Describes scripts and styles injected into matching pages.

Each entry may include:

  • matches
  • js
  • css
  • run_at
  • all_frames

Declares extension permissions such as:

  • storage
  • tabs
  • activeTab
  • scripting

Declares URL patterns the extension can access, such as:

  • *://*.example.com/*

Lists resources that extension pages or content scripts expose to matching web pages.

Defines the extension page content security policy. Maho supports the extension_pages property.

Use these fields to provide settings pages.

  • options_page points to a page path
  • options_ui supports page and open_in_tab

Registers a DevTools page for the extension.

Desktop Maho supports Manifest V3 extensions via unpacked local directories, CRX package imports, and desktop Chrome Web Store navigation intent. Manifest V2 and mobile platforms (iOS / Android) are explicitly unsupported.

  1. Unpacked Directories: Point Maho to any local directory containing a valid manifest.json.
  2. CRX Files: Import packaged .crx extension archives directly into desktop Maho.
  3. Chrome Web Store: Desktop Maho supplies Chrome Web Store User-Agent compatibility headers for store browsing and package downloads.
  • Desktop Only: Extension support is exclusive to desktop builds (macOS / Linux / Windows). Mobile shells do not support extension execution.
  • Manifest V3 Only: Manifest V2 extensions are deprecated and not supported.
  • API Availability: Extension capabilities depend on standard Chromium extension APIs exposed on desktop.

Maho follows the normal extension lifecycle for unpacked MV3 extensions.

During install, Maho:

  • Parses the manifest
  • Validates supported fields
  • Loads extension resources
  • Starts the background service worker

When enabled, Maho:

  • Injects content scripts into matching pages
  • Shows the extension action button in the toolbar
  • Makes extension APIs available to the extent they are bridged by Maho

When disabled, Maho:

  • Removes content scripts from active use
  • Hides the action button
  • Stops the service worker

When uninstalled, Maho:

  • Clears extension data
  • Wipes extension storage
  • Removes all installed resources for that extension

Content scripts use Chrome-style matching rules.

The matches field supports standard Chrome match patterns, including:

  • <all_urls>
  • *://*.example.com/*

Maho also supports glob patterns for more fine-grained URL matching where applicable.

The run_at field supports the standard MV3 injection times:

  • document_start
  • document_end
  • document_idle

Use all_frames to control whether scripts inject into subframes.

  • true injects into iframes as well as the top-level frame
  • false injects only into the top-level frame

Maho implements chrome.storage.local for extension storage.

MethodBehavior
get(keys)Retrieve stored values
set(items)Store key-value pairs
remove(keys)Delete specific keys
clear()Wipe all storage for the extension

Storage change events fire when values change. Change records include oldValue and newValue.

This lets extensions react to local state updates without polling.

Maho provides bridge APIs for communication between extension scripts and the browser.

  • chrome.tabs.query() for querying open tabs
  • chrome.runtime.sendMessage() and onMessage for extension messaging
  • Tab management APIs for creating, updating, and removing tabs

Only APIs that Maho explicitly bridges are available. Not every Chrome API is exposed.

If an extension depends on an unsupported API, it may install but fail when it tries to call that API.

For best results, keep extensions within the supported MV3 surface area:

  • Use manifest_version: 3
  • Prefer APIs Maho explicitly supports
  • Keep background logic in a service worker
  • Declare all required permissions and host permissions up front

If Maho rejects an extension at load time, check the manifest for:

  • Missing required fields
  • Invalid manifest_version
  • Version strings that do not follow semver format
  • Unsupported field shapes or values

Verify:

  • The matches patterns are correct
  • The page URL is covered by host_permissions where needed
  • run_at is set appropriately
  • all_frames matches the intended injection target

If extension state does not persist as expected, confirm that the extension is using chrome.storage.local and not relying on an unavailable storage API.

Maho’s extension support is centered on unpacked Manifest V3 extensions, Chrome-style content script matching, local storage, and a limited bridge of browser APIs. Extensions that stay within that supported surface can run in Maho with little friction.