---
title: "Ship the Safari version inside a signed · Agent Wranglers"
url: https://agentwranglers.se/playbook/desktop-apps/browser-extensions/safari-extension-packaging
id: DSK-38
level: Recommended
updated: 2026-10-27
build: a2a6bdfed830
tokens: 830
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Ship the Safari version inside a signed Apple app

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Browser extensions](https://agentwranglers.se/playbook/desktop-apps/browser-extensions.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: DSK-38
- Level: Recommended
- Chapter: [Browser extensions](https://agentwranglers.se/playbook/desktop-apps/browser-extensions.md)
- Rule: Build the Safari version of a web extension from the same source as the Chrome and Firefox versions. Wrap it in a Mac or iOS app made with Apple's packager. Test it in Safari on each release, and sign and submit it like any other app.
- Check: CI runs the packager and builds the Safari app on every release. An end-to-end test runs the extension's main flow in Safari on that build. The Safari build's extension version equals the Chrome build's version.
- How: Safari web extensions run only inside a containing app, so there is no separate extension file to upload. Apple's `xcrun safari-web-extension-packager`, formerly named `safari-web-extension-converter`, makes an Xcode project from the extension folder. It warns about manifest keys it thinks Safari does not support, so read each warning and test the feature. Keep one manifest and add the Safari wrapper in the build, so the three versions never drift apart. Safari asks the user to allow the extension per website, so test the flow where the user has not yet allowed it. The containing app is signed and notarised as [sign and notarise every Mac build](https://agentwranglers.se/playbook/desktop-apps/signing-and-notarisation/mac-notarisation.md) says, or goes through App Store review.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Shell example

```bash
xcrun safari-web-extension-packager dist/extension \
  --project-location build/safari --app-name "Ledgerly Clipper" \
  --bundle-identifier com.example.ledgerly.clipper --no-open
```

## Sources

- [Apple, Safari web extensions](https://developer.apple.com/documentation/safariservices/safari-web-extensions)
- [Apple, Packaging a web extension for Safari](https://developer.apple.com/documentation/safariservices/packaging-a-web-extension-for-safari)

## Related rules

- DSK-1 [Sign and notarise every Mac build](https://agentwranglers.se/playbook/desktop-apps/signing-and-notarisation/mac-notarisation.md) in Desktop apps and extensions

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/desktop-apps/browser-extensions/safari-extension-packaging">Agent Wranglers desktop apps and extensions playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Treat an offer to buy the extension as a threat to its users](https://agentwranglers.se/playbook/desktop-apps/browser-extensions/extension-ownership-transfer.md)
- [Browser extensions](https://agentwranglers.se/playbook/desktop-apps/browser-extensions.md)
