Chrome Extension Packaging and Release

· 4 min read

There are some pitfalls in Chrome extension development regarding packaging and distribution. Let me summarize them here.

Installation Methods

If Chrome extensions are published to the Google Store, it means users need the ability to access Google services. However, in the domestic environment, this is difficult for general users. Therefore, if targeting domestic users, alternative installation methods are needed. Currently, there are 2 approaches:

Folder Format

Folder

For folder-based extension loading, the steps are as follows:

Installation

  1. Enable Developer mode

  1. Load extension folder

    Select the plugin folder and click OK. Note that the folder must directly contain manifest.json and other essential resources. After successful installation, you’ll see the extension immediately.

CRX

For CRX files, we must upload the ZIP package to the store and then download it. Note that it doesn’t necessarily need to be published - a draft version is sufficient for downloading CRX.

Installation Method

As mentioned above, you also need to enable developer mode and drag the CRX file to chrome://extensions/. If you enabled developer mode on this page, there might be issues with drag-and-drop installation. In this case, restart the browser.

During normal installation, the following popup will appear - just click OK.

Local CRX Packaging

Besides generating and downloading CRX from the store, you can also use tools to generate CRX. However, this approach doesn’t work completely and is for reference only.

If you use local packaging tools, such as npx crx pack -p ./key.pem -o ../dist/boilerplate.crx, the generated CRX installs OK but doesn’t work. The specific error is shown below:

Therefore, for the CRX approach, downloading from the store is the only viable path.

Changing Extension ID?

Chrome’s official introduction about Extension ID:

Each app and extension has a unique identifier (ID) in the Chrome Web Store (which doesn’t change across versions). Therefore, if a user installs an app or extension on multiple devices, the app or extension will have the same ID on all devices. Each ID is 32 characters long.

Following approach 1 solves the user’s extension installation needs, but there’s still one problem: the extension ID changes. This causes issues if there’s communication between the website and extension, since the ID is used for unique extension identification.

For example, when installing the same extension in different versions, different IDs appear here:

Fixing Extension ID

Understanding the problem, how do we solve it? The solution is as follows:

  1. Build locally/use store draft method to get CRX file

  2. Visit https://robwu.nl/crxviewer/ to reverse engineer and get the key value

  3. Open console to get the key value

  4. Copy to manifest.json file

After the above operations, regardless of any device/any version extension, after installation it will have a unique extension ID. The previously generated CRX file can be deleted, and for the PEM private key, save it separately without putting it in the project.

About Key

The extension ID generation chain should be: user private key => public key => extension key => extension id. In store format, these 3 transformations are black box and users don’t need to worry about them, because when publishing and uploading, we only submit ZIP - program source files.

If users install ZIP packages, because they don’t contain extension key information, the ID won’t be fixed. The crxviewer mentioned above does reverse engineering, reads the CRX file to get the extension key, and parses the association with manifest.json. Therefore, we achieved fixed key-id for ZIP packages too. That’s how it works.

Evernote Web Clipper Plugin

I don’t know many domestic Chrome plugins, but Evernote Web Clipper is relatively familiar. Besides Google Store installation, the clipper plugin uses compressed package/folder format installation. This format can also verify the reasonableness of the above approach selection. At the same time, checking the configuration shows no key, and personally I think Evernote doesn’t have webpage-to-extension communication needs, so they didn’t choose fixed ID.

For plugin configuration development, you can download it as a reference: https://www.yinxiang.com/new/product/webclipper/install/chrome/

Summary

In conclusion, approach 2 is more convenient for users since they only need to drag CRX for installation, but development version maintenance requires manually uploading to the store and downloading each time, which is quite troublesome. Therefore, weighing the options, approach 1 ZIP/folder would be better.