Skip to content

Tested Extensions

magicelk235 edited this page Jul 29, 2026 · 14 revisions

Tested Extensions

Which extensions have actually been converted with viaduct and driven in Safari, and what happened. Nothing here comes from a clean --analyze run or a successful build: a row gets a status only after someone installed the extension and used it.

None of this is a promise. A new version of the extension, or of Safari, can invalidate any row. And when something fails because Safari can't do it at all, the row points at Limitations and FAQ instead of re-explaining it.


Contents


How to read a status

Status Meaning
Working Installed, enabled, and the extension's main job works. Minor cosmetics may still be off.
⚠️ Partial Loads and runs, but a real feature is missing. The row says which, and whether it's a viaduct gap or a platform limit.
🚧 Untested Converts and builds. Nobody has driven it in Safari yet, so it has no result.
Blocked Converts, but the thing you install it for cannot work on Safari. See Limitations and FAQ.

"Version" is the version of the Chrome extension that was converted. Extensions ship fast, so a newer build may behave differently.


Verified on the current build (1.9.x)

Extension Version MV Status Exercised
Dark Reader 4.9.128 3 ✅ Working Pages restyle dark, popup and its controls render, per-site toggles stick.
Claude in Chrome 1.0.80 3 ✅ Working Popup and side-panel toggle, including the Cmd+E open/close cycle that used to spawn a stray tab every other press (4d1109a).
TWP - Translate Web Pages 10.1.1 2 ✅ Working Toolbar button opens the real popup, page translation runs end to end. Took three fixes: the background crash and double content-script injection (7247e8b), the setPopup hijack that replaced its popup with a gray stub (6f63db2), and keeping content scripts on native messaging (4010230).
Cloaked - Privacy & Password Manager 3.6.2 3 ⚠️ Partial Popup renders, and clicking Log in opens a real Cloaked sign-in window with the extension listening on the other side. Testing stopped at the account wall, so anything behind the login (identity generation, autofill, one-time passwords) is unverified rather than known broken. Five fixes to get that far, every one of them cross-cutting: content scripts kept on native messaging (4010230), the relay Proxy that made Safari stop delivering content-script messages to extension pages (8acef29), a background page that reported FOREGROUND to its own dispatcher (cd58700), windows.create handing back a Window with no tabs (7fd15e8), and the inert onHistoryStateUpdated stub its page bridge waits on (0949657).
Tampermonkey 5.5.0 3 ⚠️ Partial Dashboard, settings and the editor all work, a userscript saves and persists, the version renders, and its registered runtime is now delivered to and evaluated on every page. Userscripts still have no effect. Tampermonkey builds its own script sandboxes: it publishes content.js and page.js through chrome.userScripts, where content.js installs a pagejs setter on a sandbox global of its own making and page.js is the assignment meant to trip it from inside that sandbox. Injecting both into the isolated world loads the runtime and wires nothing. Five viaduct bugs were fixed getting this far (3403ff7, 3dd05f2, 479d518, 937da18, 62ec130), all of which affected any extension shaped the same way.

Between them these cover most of the pipeline: manifest transform, shim injection, message routing, action wiring, and the MV3 service-worker to background-page conversion.


Verified in the June corpus round (~v1.4.0 era)

These were live-tested against the complexity corpus (see test extensions/rating) around 2026-06-23. They have not been re-checked since, and about four minor releases of shim and manifest work have landed on top, so read them as history rather than current state. Re-running any of them is a genuinely useful contribution.

Extension Status Result at the time
Grammarly ✅ Working Popup renders, account loads. Needed a five-fix chain; the unblocker was a conversion-time rewrite stripping the runtime.id + prefix out of the popup's port-routing regex, because Safari's runtime.id is the App-Extension bundle id, not the UUID in extension URLs (72c50ad).
LastPass ✅ Working Clean on the first try. Popup renders and login round-trips to LastPass servers. Smoke test only, no account, so vault and autofill are unverified.
uBlock Origin ⚠️ Partial Popup and live block counters render. Cosmetic filtering was silently dead until 622001c (viaduct's polyfill was overwriting uBlock's own copy, killing every content script after it). Actual network blocking cannot work, see below.
Bitwarden ⚠️ Partial UI loads and works. The WASM SDK and passkeys are platform limits, not conversion bugs.
Loom ⚠️ Partial Shim intact, popup blank while logged out (it opens web signup by design). tabCapture / desktopCapture are dropped, so recording is a platform limit. Logged-in flow unverified.
Honey ⚠️ Partial Background runs, network works, and a real setBadgeText init-abort got fixed out of it. Popup still comes up empty: stores:action never gets a reply on Safari. Unresolved, and the best candidate for the async-response drop.

The cross-cutting bugs this round turned up (frozen API roots aborting the shim, the immutable chrome.scripting slot, extension-UUID case mismatch, getURL("") on a frozen runtime, connect to a suspended background) are documented in Safari Quirks with the fixes that came out of them.


Converted but not driven yet

These build and install. Nobody has sat down with them in Safari, so they have no result yet.

Extension Version MV
ChatGPT 1.2.27221 3
Google Translate 2.0.17 3
Jump Cutter 1.32.2 3
Salesforce Inspector Reloaded 1.271 3
Tampermonkey BETA 5.5.6237 3
Inject Control 1.0 2

Tampermonkey BETA is the same bundle as the stable build above, one version ahead. The stable one is worth reading as a case study: getting it from "installs and registers fine" to "saves a script" took five separate fixes, and only the first two were visible before install. It ships chrome://favicon/ in permissions, which made Safari reject the whole manifest (31d13b9), and it declares webRequestBlocking over <all_urls> while building its DNR rules at runtime, which made the content-blocker check mistake a userscript manager for an ad blocker and abort the conversion (3403ff7). The other three only showed up under live use.


Convert something else instead

Instead of Convert Why
uBlock Origin (full) uBlock Origin Lite (uBOL) Blocking webRequest doesn't block on Safari. WebKit decides each request before extension JS runs and ignores your listener's return value, so no shim can change the outcome. uBOL is pure declarativeNetRequest, which Safari honors.

Any extension whose core feature is blocking webRequest, chrome.identity OAuth, cross-device storage.sync, or tabCapture lands in the same bucket. Limitations and FAQ has the full list with the real remediation for each.


Adding a result

Convert, install, and actually use the extension:

viaduct "test extensions/Some Extension.zip" --install --force --clean

Then open the background page in Safari's Web Inspector (Develop, Web Extension Background Pages) and drive the feature you'd normally use it for. The background console is reliable; the popover console is not, which is why Testing and Debugging recommends writing diagnostics to chrome.storage.local and reading them from the background.

Record a result once you can say what you did and what happened, along the lines of "popup renders and account loads". A build that merely succeeded doesn't tell anyone much. For a failure, open an issue with the converted-but-broken template, and include the extension version you used, since the next release may behave differently.

Clone this wiki locally