Creating a browser extension for Android is a task that seems difficult only at first glance. In fact, even without programming experience, you can develop a useful plugin for Chrome, Firefox or Kiwi Browserif you follow a clear algorithm. Unlike desktop versions, mobile browsers impose a number of restrictions, but also open up unique opportunities: from ad blocking to integration with Android API.
In this article we will analyze the entire process - from preparing the working environment to publishing the finished extension in Chrome Web Store or Firefox Add-ons. You'll learn what tools you'll need, how to get around the limitations of mobile browsers, and why some functions (for example, working with chrome.tabs) require a special approach on Android. We will also look at alternative ways to distribute extensions if official stores refuse to accept them.
It is important to understand that mobile extensions have less functionality compared to desktop ones. For example, Chrome for Android there is still no support background scripts in the classic form. However, with Kiwi Browser (based on Chromium) or Firefox Nightly almost any scenario can be implemented. If your goal is maximum compatibility, you will have to adapt the code for each browser separately.
1. Selecting a browser and preparing tools
Before starting development, decide on the target browser. Not all mobile browsers support extensions, and those that do do so in different ways. Here are the key options: Android support extensions, and those that do support them do it differently. Here are the key options:
- ๐ Kiwi Browser โthe best choice for extensions based on Chromium. Supports most desktop APIs, including Chrome, including
chrome.storageandchrome.notifications. - ๐ฆ Firefox for Android - supports extensions via WebExtensions, but with limitations. For example, there is no access to the mobile version. Firefox for Android does not officially support extensions (except for enterprise mode). However, you can use workarounds, which we will discuss below.
browserActionin the mobile version. - ๐ซ Google Chrome for Android โ does not officially support extensions (except for enterprise mode). However, you can use workarounds, which we will discuss below.
- ๐ก๏ธ Brave Browser - supports extensions, but requires manual installation via
adb.
For development you will need:
- ๐ป Computer with Windows, macOS or Linux (mobile development "on the knee" is possible, but inconvenient).
- ๐ฑ Android-device with software debugging enabled USB (
Settings โ About phone โ Number builds- tap 7 times). - ๐ง Android Studio (for debugging through
adb) or Visual Studio Code with extension Live Server. - ๐ฆ Node.js (for building projects with
webpackorParcel).
โ ๏ธ Attention: If you plan to test the extension on Chrome for Android via enterprise policies, please note that this method requires an enterprise license Google Workspace. Without it, extensions will not work.
For convenience, we recommend starting with Kiwi Browser โit is closest to the desktop Chrome and allows you to test extensions without additional manipulations. Install it from Google Play and enable developer mode in the browser settings (kiwi://extensions).
2. Extension structure: which files are required
Any browser extension consists of a set of files with a clear structure. The minimum set includes:
- ๐
manifest.jsonโ the โheartโ of the extension, which describes rights, versions and resources. - ๐
icons/โ a folder with icons for different resolutions (16x16, 48x48, 128x128). - ๐
popup.html(optional) - HTML page that opens when you click on the extension icon. - ๐
background.jsorservice-worker.js- script for background tasks (works with limitations in mobile browsers). - ๐
content.js- script that runs on website pages.
Example minimum manifest.json for Kiwi Browser:
{"manifest_version": 3,
"name": "My extension",
"version": "1.0",
"description": "Test extension for Android",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icons/icon48.png"
},
"permissions": ["storage", "activeTab"]
}
In mobile browsers manifest_version there should be 3 (and not 2, as in old desktop extensions). Also note that some permissions (for example "tabs") may not work or require additional right.
| File/folder | Required? | Purpose |
|---|---|---|
manifest.json |
Yes | Extension configuration, access rights, metadata. |
icons/ |
Yes | Icons for display in the browser panel and store. |
popup.html |
No | Pop-up window interface when you click on the icon. |
background.js |
No | Background tasks (works to a limited extent in mobile browsers). |
content.js |
No | Scripts executed on web pages. |
โ ๏ธ Attention: In Firefox for Android are not supportedbrowserActionandpageActionfrommanifest.json. Instead, usesidebar_actionor adapt the UI to a mobile interface.
Create a project folder|Add manifest.json|Prepare icons of different sizes|Write popup.html (if needed UI)|Check permissions in manifest.json-->
3. Development of functionality: from simple to complex
Start with a simple extension that performs one task. For example, let's replace all the images on the site with random pictures of cats. To do this, you only need content.js and manifest.json.
Add to manifest.json permission to work with the active tab:
"permissions": ["activeTab"],"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
Now create content.js:
document.querySelectorAll('img').forEach(img => {img.src = 'https://placekitten.com/' + img.width + '/' + img.height;
});
This script replaces all images (<img>) on the website for random pictures of cats from the service placekitten.com. To test it:
- Go to Kiwi Browser and open
kiwi://extensions. - Enable Developer mode (toggle in the upper right corner).
- Click Load unpacked extension and select the folder with your project.
If everything is done correctly, when you open any site, all images will be replaced with cats. This example demonstrates the basic principle of operation content_scriptsbut in real projects you will need more complex mechanisms.
For debugging content.js use Chrome DevTools on a computer. Connect to Androiddevice via adb and open chrome://inspect in desktop Chrome.
4. Working with storage and settings
Most extensions require data to be saved between sessions - for example, user settings or cache. In browsers on Android this is done using chrome.storage (in Chromium) or browser.storage (in Firefox).
An example of saving and reading data in Kiwi Browser:
// Saving datachrome.storage.sync.set({ color: 'red' }, () => {
console.log('Color saved');
});
// Reading data
chrome.storage.sync.get(['color'], (result) => {
console.log('Current color: ' + result.color);
});
In Firefox for Android syntax similar, but instead chrome. is used browser.:
browser.storage.local.set({ key: 'value' });
Pay attention to two types of storage:
- ๐
storage.sync- synchronized with the account Google (v Chrome) or Firefox. Suitable for small data (~5 MB limit). - ๐พ
storage.local- stored only on the device. Limit ~5 MB in Chrome and ~10 MB in Firefox.
โ ๏ธ Attention: In mobile browsers. data-i="171">may be unstable due to background activity restrictions. Test saving data on a real device, not in the emulator. storage.sync May be unstable due to background activity restrictions. Test saving data on a real device, not in an emulator.
For complex data (for example, lists of blocked sites), it is better to use IndexedDB via window.indexedDB v content_scripts. However, note that IndexedDB is tied to the site domain, not the extension.
How to bypass the storage.sync limitation in Firefox for Android?
v Firefox for Android storage.sync is not supported at all. Instead, use storage.local or implement your own synchronization via Firebase or another cloud service. This will require a backend, but this is the only way to synchronize data between devices.
5. Testing and debugging on an Android device
Testing extensions on Android is different from desktop development. Here are the key steps:
- Connect via ADB:
Make sure that software debugging is enabled on your device USB (
Settings โ System โ For Developers). Connect the device to the computer and do:adb devicesIf the device is not displayed, install drivers ADB for your model Android.
- Installing an extension:
Download the extension via Kiwi Browser download the extension via
kiwi://extensions. In Firefox use WebExt Tool:web-ext run --target=firefox-android --android-device=DEVICE_ID - Debugging:
For Chromiumbrowsers open
chrome://inspecton your computer, select your device and click Inspect next to the extension tab. To Firefox use about:debugging.
Frequent problems during testing:
- ๐ Extension does not load - check
manifest.jsonfor errors (for example, incorrect versionmanifest_version). - ๐ต ADB does not see the device โ restart the device and computer, check the cable USB (itโs better to use the original one).
- ๐ซ No access to API โsome permissions (for example,
"tabs") may be blocked in the mobile version.
Test the extension on a real device, not just in the emulator. Many errors (for example, related to permissions) appear only on physical devices.
6. Publish the extension: Chrome Web Store vs. Firefox Add-ons
When the extension ready, it can be published in official stores. The process is different for Chrome Web Store and Firefox Add-ons.
Publishing in the Chrome Web Store
Algorithm for Kiwi Browser (and other Chromiumbrowsers):
- Create a ZIP archive with extension files (without a folder).
- Register as a developer in Chrome Web Store (one-time payment $5).
- Upload the archive to DevConsole, fill in the metadata (description, screenshots, category).
- Pay for publication (if this is your first extension).
- Wait for moderation (usually 1-7 days).
Publishing in Firefox Add-ons
For Firefox the process is simpler:
- Create a ZIP archive (similar to Chrome).
- Register on AMO (free).
- Download the extension via Developer Hub. Firefox does not charge for publication.
- Go through automatic and manual moderation (usually 1-3 days).
Restrictions for mobile extensions:
- ๐ฑ Q Chrome Web Store extensions for Android are not allocated to a separate category Please indicate in. description that it is intended for mobile devices.
- ๐ Firefox requires separate verification for the mobile version. If your extension uses an unsupported API, it may be rejected.
โ ๏ธ Attention: If your extension modifies pages (for example, blocks ads), it may be rejected by Chrome Web Store according to policy Google. In this case, consider alternative distribution methods (see the next section).
How to publish an extension without moderation?
The only legal way is to distribute the extension as a .crxfile through your website. manually via kiwi://extensions (in Kiwi Browser) or about:debugging (in Firefox). However, this method requires users to enable developer mode, which is inconvenient.
7. Alternative distribution methods
If your extension has not been moderated in official stores (for example, due to ad blocking), there are workarounds:
- ๐ Self hosting:
Post the extension files on your website or GitHub. Users will be able to download the ZIP archive and download it manually via
kiwi://extensions(for Kiwi Browser) orabout:config(for Firefox). - ๐ฆ APK with a pre-installed extension:
Build a modified version Kiwi Browser or Firefox with a built-in extension. This will require assembly skills APK from sources.
- ๐ Link to install via ADB:
Provide users with a command to install via
adb:adb install-extension --package-name=com.kiwibrowser.browser PATH_TO_EXTENSION
Advantages and risks of alternative methods:
| Method | Pros | Cons |
|---|---|---|
| Self hosting | No moderation, full control | Users must manually enable developer mode |
| APK with extension | Convenient for users (installation as a regular application) | Requires updating the entire APK when changing the extension |
| Installation via ADB | Works without developer mode in the browser | Requires a connection to a PC and knowledge of commands adb |
If you choose self-distribution, make sure that your site is protected by HTTPSand the extension files do not contain malicious code Users must trust the source, so add instructions for. checking the integrity of files (for example, through hash sums SHA-256).
8. Optimization for mobile devices
Extensions on Android should take into account the features of the mobile interface:
- ๐ฑ Responsive design:
If your extension has
popup.htmlmake sure that it displays correctly on small devices screens. Use media queries@mediato adapt:@media (max-width: 400px) {body { font-size: 14px; }
button { padding: 8px; }
} - ๐ Save battery:
Avoid constant activity in the background. In mobile browsers, background scripts (
background.js) are often suspended by the system to save energy. - ๐ Performance:
Optimize the code so that it does not slow down the browser. For example, instead of
setIntervaluserequestIdleCallbackfor background tasks.
Example of optimized content.js for mobile devices:
// Bad: constant DOM pollingsetInterval(() => {
document.querySelectorAll('img').forEach(img => { ... });
}, 1000);
// Good: using MutationObserver
const observer = new MutationObserver((mutations) => {
mutations.forEach(() => {
document.querySelectorAll('img:not(.processed)').forEach(img => {
img.src = 'https://placekitten.com/200/200';
img.classList.add('processed');
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
In mobile browsers MutationObserver consumes less resources than setInterval, since it only fires when there are changes in the DOM.
Test the extension on devices with different screen resolutions and versions Android. What works on a flagship may slow down on a budget smartphone.
FAQ: Frequently asked questions about developing extensions for Android
Is it possible to make an extension for Chrome on Android without Kiwi Browser?
Officially - no. Google Chrome for Android does not support extensions for ordinary users. However, there are workarounds: Google Chrome for Android data-i="316">with superuser rights (root required).
- Use Chrome in enterprise mode (Volume license required).
- Install the extension via
adbwith superuser rights (root required). - Use alternative browsers (Kiwi, Firefox, Brave).
How to update the extension for users if it is installed manually?
When you distribute it yourself, updates do not occur automatically. You need to:
- Change the version in
manifest.json(for example, from"1.0"to"1.1"). - Collect a new ZIP archive and place it on the site.
- Inform users about the need to reinstall the extension.
Automatic updates require publishing to Chrome Web Store or Firefox Add-ons.
Why does my extension work on PC, but not on Android?
Main reasons:
manifest_versionthere should be 3 (version 2 is also found in desktop extensions).- Some APIs (for example,
chrome.tts) are not supported on mobile browsers. - Restrictions on background scripts - in Android they can be suspended.
- Lack of rights to some permissions (for example,
"management").
Check the logs through Chrome DevTools or Firefox Debugger on a real device.
Is it possible to make money on mobile extensions?
Yes, but it is more difficult than on desktop ones. The main methods of monetization:
- ๐ฐ Paid publication - selling extensions in stores (for example, via Gumroad).
- ๐ข Advertising โ integration of banners into
popup.html(but this may cause rejection during moderation). - ๐ Freemium model โ basic version free, premium features for fee.
- ๐ค Affiliate apps โ if the extension is associated with a specific service (for example, VPN).
Please note that mobile users are less likely to pay for extensions than desktop ones.
How to protect extension code from copying?
It is impossible to completely protect JavaScript code, but you can complicate the task:
- Use obfuscators (for example, JavaScript Obfuscator).
- Move critical logic to the backend (for example, via Cloud Functions).
- Add a license check when loading the extension.
- Distribute the extension in closed communities (for example, via Patreon).
Remember that obfuscation can slow down the extension on weaker users) devices.