How to Build and Publish Browser Extensions for Chrome, Firefox, and Safari

Article summary

Developing browser extensions can seem daunting, especially when targeting multiple browsers like Chrome, Firefox, and Safari. Each platform has its own set of requirements, tools, and submission processes, which can be overwhelming for developers new to the ecosystem. This guide aims to simplify the process by breaking it down into manageable steps. Whether you’re building your first extension or adapting an existing one for cross-browser compatibility, this post will provide a practical starting point.

Chrome

First, let’s look at files and submission processes in Chrome.

Files

  • manifest.json – must include manifest_version, name, and version
{
  "manifest_version": 3,
  "name": "My Chrome Extension",
  "version": "1.0",
  "description": "An example Chrome extension.",
  "permissions": ["storage", "activeTab"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "content_scripts": [
    {
      "matches": [""],
      "js": ["content.js"],
      "css": ["styles.css"]
    }
  ],
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "host_permissions": [""]
}
  • HTML, CSS, and JS files
    • popup.html – create a user interface for the popup that appears when the user clicks the extension
    • content.js – content script that runs when the page loads
    • background.js – script that runs in the background
    • styles.css – any custom CSS that you’d like to add
  • Icons folder – PNG files in sizes 16×16, 48×48, and 128×128 for the Chrome Web Store and browser UI

Submission Process

Platform: Chrome Web Store

Account Requirements: Google Developer Account ($5 one-time registration fee)

Submission Steps:

  • Package your extension into a .zip file.
  • Upload the .zip to the Chrome Web Store Developer Dashboard.
  • Fill out metadata (description, screenshots, promotional images).
  • Submit for review.

Note: For more information on creating your first Chrome extension, see this post!

Firefox

Now, let’s look at files and submission processes in Firefox.

Files

  • manifest.json – must include manifest_version, name, and version. You may need to specify an ID (see browser_specific_settings in this example)
{
  "manifest_version": 3,
  "name": "My Firefox Extension",
  "version": "1.0",
  "description": "An example Firefox extension.",
  "permissions": ["storage", "activeTab"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "content_scripts": [
    {
      "matches": [""],
      "js": ["content.js"],
      "css": ["styles.css"]
    }
  ],
  "icons": {
    "48": "icons/icon48.png",
    "96": "icons/icon96.png"
  },
  "host_permissions": [""],
  "browser_specific_settings": {
    "gecko": {
      "id": "[email protected]"
    }
  }
}
  • HTML, CSS, and JS files – same as Chrome
  • Icons folder – PNG files in sizes 48×48, and 96×96
  • Additional tools: Mozilla’s web-ext command-line tool simplifies testing and packaging (optional)

Submission Process

Platform: Firefox Add-ons

Account Requirements: Mozilla Developer Account (free)

Submission Steps:

  • Package your extension using web-ext or manually zip the files.
  • Upload to the Firefox Add-ons Developer Hub.
  • Fill out metadata (description, screenshots).
  • Submit for review.

Safari

And finally, here’s what you should know about files and submission processes in Safari.

Files

  • manifest.json – must include manifest_version, name, and version. Icons are required in multiple sizes for compatibility with the Safari toolbar and App Store.
{
  "manifest_version": 3,
  "name": "My Safari Extension",
  "version": "1.0",
  "description": "An example Safari extension.",
  "permissions": ["storage", "activeTab"],
  "background": {
    "service_worker": "background.js"
  },
  "browser_action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/toolbar-icon16.png",
      "19": "icons/toolbar-icon19.png",
      "32": "icons/toolbar-icon32.png",
      "38": "icons/toolbar-icon38.png"
    }
  },
  "content_scripts": [
    {
      "matches": [""],
      "js": ["content.js"],
      "css": ["styles.css"]
    }
  ],
  "icons": {
    "48": "icons/icon48.png",
    "64": "icons/icon64.png",
    "96": "icons/icon96.png",
    "128": "icons/icon128.png",
    "256": "icons/icon256.png",
    "512": "icons/icon512.png"
  },
  "host_permissions": [""],
  "browser_specific_settings": {
    "safari": {
      "background": {
        "service_worker": "background.js"
      }
    }
  }
}
  • Info.plist – a required property list file describing your extension for macOS and Safari.
<plist version="1.0">
<dict>
  <key>CFBundleDisplayName</key>
  <string>My Safari Extension</string>
  <key>CFBundleIdentifier</key>
  <string>com.example.myextension</string>
  <key>CFBundleVersion</key>
  <string>1.0</string>
</dict>
</plist>
  • HTML, CSS, and JS files – same as Chrome and Firefox.

Submission Process

Platform: Apple App Store

Account Requirements: Apple Developer Program membership ($99/year)

Submission Steps:

  • Build the macOS app in Xcode, bundling your extension.
  • Test using Safari’s extension developer mode.
  • Submit the app and extension to the Mac App Store for review.

While developing browser extensions for Chrome, Firefox, and Safari involves some effort, it is rewarding. By following the outlined steps and understanding each platform’s unique requirements, you’ll be well on your way to creating extensions that enhance users’ browsing experiences. Take your time, test thoroughly, and enjoy the process of bringing your ideas to life.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *