chrome-extension anatomy and how its parts communicate

Ahmad Ali
3 min readNov 21, 2020

--

There are lots of resources out there talking about extensions. here is one chart that contains every single layer and the relationships between them.

why you can listen to me: well, just check out my website (https://ahmad-ali.co.uk/) or my Github ( https://github.com/ahmad-ali14/) and decide that yourself.

chrome extension contains 6 important files:

  1. manifest.json: organises the extension structure ( somehow similar to package.json).
  2. background script: This resource is shared between all browser windows and every element inside them (so changing a value in the background will change it everywhere on the browser instantly).
  3. popup script: contains the markup that the extension displays when you click on its icon, it is containable in the single tab, does not have access to the extension background or page content but it can communicate with them through messages as:
    a. chrome.runtime API to communicate with the background.
    b. chrome.tabs API to communicate with its tab.
  4. content scripts: it is containable in the page window so it has access to the page DOM, it does not have an actual effect on the extension itself unless it starts communicating with the background and popup scripts through messaging events.
  5. options script: this is a special file that allows you to give the user some options in order to personalise their extension as they want, any piece of an option can be saved to the chrome.storage.local and can be synchronised between multiple browsers where the user logged in to chrome using chrome.storage.sync.
  6. icons files: should be in sizes like 1616 and 3232px, the paths to those files should be specified in the manifest.

Communication between different scripts:

1. From everywhere to background scripts and vice versa:

you can use ** chrome.runtime.sendMessage()** or any other runtime events, you need an eventListener in the background, which in turn will handle the request and dispatch its response everywhere.
and in order to receive that message (or response) you need another eventListener on the other script listening to the runtime events.

2. From popup to content and vice versa:

you can’t communicate directly between those 2 scripts. since both scripts can communicate with the background we can use it as middleware between them or we can use the tabs API.

first: background as middleware

you can use chrome.runtime API to exchange messages between the script you are in (popup or content) and the background using the chrome.runtime.sendMessage(), the background will send its response to everywhere.
In order to receive the message, you need to listen to it on the other script itself.
so:

  1. you send a message from popup to the background.
  2. the background will handle the request and send its response to everywhere.
  3. both popup and content scripts are containable in everywhere (check the chart).
  4. you can listen to that response either in popup or content or both, so you received the message.
  5. done !!

second: create a connection between popup and content through the tab

you can use chrome.tabs API to create a connection between the popup and the content script using the chrome.tabs.connect() and then postMessage through the tab background.
in order to receive the message, you need to listen to it on the script itself.
so:

  1. you open a port between popup and content through the tab background.
  2. you send a message through that port to the tab background.
  3. tab background will redirect it to the content script which will handle the request and send it through the same port to the popup.
  4. you can listen to that response either in the popup, so you received the message.
  5. you can close the port, or leave it open to send other messages.
  6. done !!

--

--