Web Extension Messenger

0.35.0 · active · verified Sun Apr 19

webext-messenger is a focused JavaScript library designed to streamline inter-component communication within browser extensions. It provides a robust framework for message passing between different parts of an extension, such as background scripts, content scripts, and web pages, as well as offscreen documents. The current stable version is 0.35.0, with frequent minor releases indicating active development, often introducing new features and internal optimizations. A key differentiator is its emphasis on minimizing external dependencies, aiming for a lightweight footprint, as evidenced by recent efforts to drop libraries like `p-retry` and `webextension-polyfill` for core functionality. This library simplifies complex messaging patterns, abstracting away the underlying browser `runtime.sendMessage` and `runtime.onMessage` APIs to offer a more developer-friendly interface for building robust and scalable browser extensions.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates basic inter-component communication between a background service worker and a content script using `webext-messenger`. It shows how to initialize messengers in different contexts, set up message listeners, and send messages with data, including handling responses and errors across extension components. The manifest is provided for a complete example.

/* === manifest.json (Manifest V3) === */
{
  "manifest_version": 3,
  "name": "Webext Messenger Demo",
  "version": "1.0",
  "permissions": ["activeTab", "scripting"],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "host_permissions": ["<all_urls>"]
}

/* === background.js === */
import messenger from 'webext-messenger';

const backgroundMessenger = messenger.init('background');

backgroundMessenger.onMessage('ping', (data, sender) => {
  console.log('Background received ping:', data, 'from', sender.tab?.url);
  return { response: 'pong from background', receivedData: data };
});

backgroundMessenger.onMessage('logTabUrl', async (data, sender) => {
  console.log('Background received logTabUrl request for tab ID:', data.tabId);
  try {
    const tab = await chrome.tabs.get(data.tabId);
    return { url: tab.url };
  } catch (error) {
    console.error('Error getting tab:', error);
    return { error: error.message };
  }
});

console.log('Background script initialized with webext-messenger');

/* === content.js === */
import messenger from 'webext-messenger';

const contentMessenger = messenger.init('content-script');

contentMessenger.onMessage('alertUser', (message) => {
  alert('Message from background: ' + message);
  return 'Alert shown!';
});

async function sendPingToBackground() {
  console.log('Content script sending ping...');
  try {
    const response = await contentMessenger.sendMessage('background', 'ping', { message: 'Hello from content!' });
    console.log('Content received response from background:', response);
  } catch (error) {
    console.error('Content script failed to send ping:', error);
  }
}

async function requestBackgroundForTabUrl() {
  console.log('Content script requesting current tab URL from background...');
  try {
    const tabId = await new Promise(resolve => chrome.tabs.getCurrent(tab => resolve(tab.id)));
    const response = await contentMessenger.sendMessage('background', 'logTabUrl', { tabId: tabId });
    console.log('Content received tab URL from background:', response.url);
  } catch (error) {
    console.error('Content script failed to request tab URL:', error);
  }
}

// Run these after a short delay to ensure messenger is ready
setTimeout(() => {
  sendPingToBackground();
  requestBackgroundForTabUrl();
}, 1000);

console.log('Content script initialized with webext-messenger');

view raw JSON →