bork for Android: GeckoView, full uBlock Origin and bork's own add-ons on a phone
  • JavaScript 32.6%
  • Kotlin 29.5%
  • Swift 27.7%
  • CSS 4.9%
  • HTML 2.6%
  • Other 2.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
100mountains 08cdf16d6d iOS app: bork on WebKit, with bork's add-ons on a runtime of its own
iOS allows no engine but WebKit, and WebKit runs no extensions in an
app, so this is a second shell rather than a port of the Android one:
Swift and UIKit, the same workspaces, zen mode, start page, tab tray,
private tabs, desktop site, find, downloads, history and bookmarks.

- ExtensionRuntime + extension-api.js: a small WebExtension runtime.
  YouTube Manager and Cyberswine run from their unchanged files —
  content scripts in an isolated content world per add-on, background
  pages in hidden web views, extension pages on bork-ext://, and
  storage, runtime messaging, tabs.* and blocking webRequest bridged to
  native. Messages are only accepted from the add-on's own world or
  pages.
- ContentBlocker: EasyList + EasyPrivacy as a WebKit content rule list
  (tools/build-blocklist.py, ~120k rules), with a per-site off switch.
  This is what blocks ads where uBlock Origin cannot run.
- Runs on iOS 17+: WebKit's Swift overlay is avoided and weak-linked,
  since only iOS 26 ships it.

Verified on the iPhone 16 Pro simulator (iOS 18.5): channel blocking
and SHUT UP on m.youtube.com, Cyberswine redirecting a blocked outlet
to its explanation page, session restore, blocklist compiled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:38:00 +01:00
android Split into android/ and shared/extensions/ ahead of the iOS app 2026-10-19 18:19:20 +01:00
docs/screenshots iOS app: bork on WebKit, with bork's add-ons on a runtime of its own 2026-10-19 18:38:00 +01:00
ios iOS app: bork on WebKit, with bork's add-ons on a runtime of its own 2026-10-19 18:38:00 +01:00
shared/extensions Split into android/ and shared/extensions/ ahead of the iOS app 2026-10-19 18:19:20 +01:00
tests Split into android/ and shared/extensions/ ahead of the iOS app 2026-10-19 18:19:20 +01:00
tools iOS app: bork on WebKit, with bork's add-ons on a runtime of its own 2026-10-19 18:38:00 +01:00
.gitignore bork mobile: GeckoView browser for Android with bork's add-ons 2026-10-19 15:21:32 +01:00
AGENTS.md iOS app: bork on WebKit, with bork's add-ons on a runtime of its own 2026-10-19 18:38:00 +01:00
CLAUDE.md bork mobile: GeckoView browser for Android with bork's add-ons 2026-10-19 15:21:32 +01:00
LICENSE bork mobile: GeckoView browser for Android with bork's add-ons 2026-10-19 15:21:32 +01:00
README.md iOS app: bork on WebKit, with bork's add-ons on a runtime of its own 2026-10-19 18:38:00 +01:00

bork mobile

bork for phones: Android and iOS, one repo, the same add-ons.

android/            Gecko (GeckoView) app — Kotlin
ios/                WebKit app — Swift, UIKit
shared/extensions/  bork's add-ons, used by both
tools/              add-on sync, blocklist builder
tests/              host tests for the mobile YouTube script

The two are not the same browser. Android runs Gecko, Firefox's engine, so Manifest V2 extensions run there for real: the complete uBlock Origin, not the Lite version, plus Dark Reader and bork's own add-ons. iOS allows no engine but WebKit, and WebKit runs no extensions inside an app — so the iOS app carries bork's own two add-ons on a small extension runtime of its own, and blocks ads with WebKit's content rule lists instead of uBlock. Everything else — workspaces, zen mode, the start page, the look — is the same on both.

What both do

  • Workspaces — named sets of tabs, like the desktop's. Switch them from the chips at the top of the tab tray; long-press a tab to move it to another workspace, long-press a workspace to rename or delete it. The badge left of the address bar shows which one you are in (tap it for the tray, long-press it to jump to another).
  • Zen mode — toolbars and status bar gone, only the page. A faint dot on the right edge brings them back.
  • Start page — pinned sites as tiles. Pin a page from the menu; long-press a tile to rename, reorder or unpin it.
  • Private tabs, desktop site per tab, find in page, downloads, bookmarks and history (on the phone and nowhere else), tabs that come back after a restart, the address bar at the bottom if you prefer it.
  • No telemetry, no crash reports, no accounts.

Add-ons

Android iOS
uBlock Origin the AMO-signed build the desktop ships, full MV2 — (WebKit cannot run it); EasyList + EasyPrivacy as a WebKit content blocker instead, with a per-site off switch
Dark Reader yes —
YouTube Manager yes, ported to m.youtube.com (below) yes, the same files, on bork's extension runtime
Cyberswine yes, plus a contextMenus shim yes, the same files; its navigation blocking runs through the runtime's webRequest bridge
Anything from addons.mozilla.org installs —

Each add-on with a toolbar button is in the menu and opens its popup in a sheet; their settings pages open in tabs.

YouTube Manager on a phone

The desktop add-on is built around a mouse: a floating bar follows the pointer over video cards, and HIDE drives YouTube's own ⋮ menu. None of that translates, so the mobile version keeps the same settings, store and matching (filters.js and friends are the desktop files, copied unchanged) and replaces only the part that touches YouTube's pages:

Desktop Mobile
Channel blocking on home, search, the watch sidebar, Shorts Kept, on m.youtube.com's markup (and the desktop site, if you ask for it)
SHUT UP in a bar that follows the pointer A SHUT UP button under every video card, and one beside Subscribe on the watch page
Subscription tabs + TAG Kept: tabs at the top of the subscriptions feed, a TAG button under each video, a bottom sheet to pick the tab
Shorts switch on the subscriptions feed Kept
Live chat filtering, SHUT UP per message, threaded view Kept — m.youtube.com does not show live chat, so live watch pages get a CHAT button that opens YouTube's own chat page in a new tab, where the desktop chat code runs unchanged. Tap a message to show its SHUT UP
HIDE / DONE (presses YouTube's ⋮ → Hide) Stripped — the mobile menu is a different bottom sheet; pressing it for you would be guesswork
Watch tab saves with YouTube's Save to Watch later Stripped — the Watch tab still holds single videos, as a note kept here only
End-of-video suggestion wall Stripped — the mobile player does not build one
"Who do I subscribe to" from the guide drawer Replaced — the mobile site has no drawer; Subscribe buttons and the subscriptions feed's channel strip say it instead, and it is remembered

The iOS extension runtime

ios/Bork/Extensions/ runs bork's add-ons from their own unchanged files: content scripts in an isolated WebKit content world per add-on, background pages in hidden web views, extension pages on bork-ext://, and browser.storage, runtime messaging, tabs.query/sendMessage/create, and blocking webRequest for top-level navigations — the API surface bork's add-ons use, not all of WebExtensions. A message is accepted only from the add-on's own content world or its own bork-ext:// pages, so no web page can reach an add-on's storage.

Building

Android

Needs the Android SDK with platform 37.2 and JDK 17+ (Android Studio's bundled one works).

cd android
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
./gradlew :app:assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

iOS

Needs Xcode 26 (iOS 17+ deployment target; runs on iPhone and iPad, and on Apple Silicon Macs as an iPad app).

cd ios
xcodegen generate        # only after editing project.yml; the project is committed
xcodebuild -project Bork.xcodeproj -target Bork -sdk iphonesimulator -arch arm64 \
  SYMROOT=build/Build/Products CODE_SIGNING_ALLOWED=NO build
xcrun simctl install booted build/Build/Products/Debug-iphonesimulator/Bork.app

Or open ios/Bork.xcodeproj in Xcode and run. A device build needs your own signing team.

Tests

deno test --allow-read tests/

The YouTube Manager mobile script against markup captured from the real m.youtube.com. No browser, no network.

Keeping the add-ons in step with the desktop

tools/sync-extensions.sh            # expects ../bork-browser next to this repo

It copies the files shared with the desktop into shared/extensions/ and never touches the mobile-only ones (listed at the top of the script). Bump the mobile manifest.json version afterwards — Android only reloads a built-in add-on when its version changes.

The iOS blocklist is rebuilt from the current EasyList and EasyPrivacy with:

tools/build-blocklist.py ios/Bork/Resources/blocklist.json

License

Mozilla Public License 2.0, as bork. The iOS blocklist is derived from EasyList and EasyPrivacy by The EasyList authors, dual-licensed GPLv3 / CC BY-SA 3.0 and used here under CC BY-SA 3.0.

bork is based on Floorp, which is based on Mozilla Firefox. It is not affiliated with, endorsed by, or connected to Mozilla, Ablaze or the Floorp project. GeckoView is Mozilla's, MPL 2.0.