Skip to content

Instantly share code, notes, and snippets.

@rxliuli
Last active April 26, 2025 01:23
Show Gist options
  • Save rxliuli/940584d75f55de3a4e9e2c5682bbcae8 to your computer and use it in GitHub Desktop.
Save rxliuli/940584d75f55de3a4e9e2c5682bbcae8 to your computer and use it in GitHub Desktop.
Converting Chrome Extensions to Safari

Converting Chrome Extensions to Safari

Background

I recently attempted to convert a Chrome extension to Safari—something I had postponed due to Xcode's poor development experience. This article documents the conversion process for Redirector, which is already available on Chrome/Firefox/Edge, into my first Safari extension on the App Store.

Conversion Process

WXT's documentation mentions how to publish Safari versions using the xcrun command line tool for converting Chrome extensions to Safari format.

Since I used Manifest V3, the command is:

pnpm wxt build -b safari
xcrun safari-web-extension-converter --bundle-identifier com.rxliuli.redirector --force .output/safari-mv3

This generates an Xcode project and automatically opens it.

Building and Testing

After building in Xcode, Safari won't show the extension by default because Safari doesn't allow unsigned extensions.

1741855496643.jpg 1741855508793.jpg

1741855578407.jpg

To enable testing:

  1. Go to Safari > Settings > Advanced > Show features for web developers 1741855703402.jpg
  2. Then Safari > Settings > Developer > Allow unsigned extensions 1741855678560.jpg

If you've previously installed and uninstalled this extension, you'll need to specify a different project location:

pnpm wxt build -b safari
xcrun safari-web-extension-converter --bundle-identifier com.rxliuli.redirector --force --project-location 'Redirector 2025-03-13-17-20' .output/safari-mv3

You can check recognized extensions with:

pluginkit -mAvvv -p com.apple.Safari.web-extension

If everything works, you'll see the extension in Safari's Extensions panel. 1741858042811.jpg

Enable it to see the extension icon in Safari's toolbar. 1741858161233.jpg

If you find development in the Mac ecosystem painful, with things often not working without any error messages, this is unfortunately "normal."

Adapting Incompatible APIs

Safari has several incompatible APIs with Chrome extensions. These won't produce errors but simply won't work. You can check the official compatibility documentation for incompatible APIs.

For example, webRequest APIs: Safari doesn't support webRequest API functionality in Manifest V3 at all, and it only works in Manifest V2 persistent background pages (which iOS doesn't support).

For Redirector, I had to replace: browser.webRequest.onBeforeRequest.addListener with browser.webNavigation.onCommitted.addListener

You can refer to the official documentation to debug background scripts. It's inconvenient, but it's the only method available.

Now the extension works correctly:

<iframe width="560" height="315" src="https://www.youtube.com/embed/GjVY7fELWts?si=uHWOuA50JA2RJzLH" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

Publishing to the App Store

To prepare for App Store submission:

  1. Configure Project > Build Settings > Development Team 1741836712437.jpg

  2. Select an App Category under Mac/iOS Targets 1741837528537.jpg

  3. Update the version number manually (it doesn't follow the manifest version) 1741862590410.jpg

The version is also in <project name>/<project name>.xcodeproj/project.pbxproj file, search and replace MARKETING_VERSION = 1.0;

Build with Product > Archive 1741862602934.jpg

First click Validate App to check for configuration errors. I encountered an error that my extension name already exists. 1741862725322.jpg

After modifying the name in the manifest and repeating the conversion and build process, validation succeeded. 1741863485137.jpg

Then click Distribute App and select App Store Connect for App Store distribution or Direct Distribute for notarization. 1741864293656.jpg

I found this video very helpful https://youtu.be/s0HtHvgf1EQ?si=rbzc88E1Y_6nZY6k

Completing Publication Information

Finally, go to App Store Connect to complete publication details including screenshots, privacy policy, and pricing. I didn't realize Apple manages app publishing through a website rather than through one of their apps, which led to a two-week delay.

Note that emoji characters are not allowed in App descriptions.

Conclusion

Mac/iOS development is a very closed platform with development tools and experiences quite different from the Web. However, considering Safari is the default browser on Mac and the only option on iOS, it's worth supporting despite being even worse than Firefox.


The extension has been published to the App Store: https://apps.apple.com/app/id6743197230

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment