The copy-paste shuttle
Open a gallery page on a file host. You see twelve links you want. Right-click the first, copy, switch to the download manager, paste. Back to the browser. Right-click the second, copy, switch, paste. On the seventh link you lose your place, and you're never really sure whether you grabbed everything.
I resent browser extensions on principle, which made this a hard call. But the copy-paste shuttle was the single biggest complaint in my inbox, so I held my nose and built one. The Veloxar Companion extension makes that shuttle one click. It just landed, and this post is about the architecture behind a feature that looks, from the outside, like it could not possibly need any.
Local bridge, not cloud bounce
The obvious way to build a browser-to-app bridge in 2026 is to punt: ship the URL up to a cloud service, poll for it from the desktop app, done. It works, and it's wrong for this problem.
Your browser and your download manager are on the same laptop, inches apart in silicon. Routing a URL through a datacenter in another state so the app can pull it back adds latency, a failure mode, and a dependency on whether somebody remembered to pay the AWS bill. A cloud bridge also means every link you send passes through somebody else's database. Even if that somebody is us. Especially if that somebody is us. The best way to not leak a list is to never have it.
And if Veloxar's servers ever go down, your download manager should not notice. With a cloud bridge it would notice instantly -- a local problem becomes everybody's problem.
So we didn't. The extension talks to the desktop app over plain
HTTP on localhost. The desktop app opens a
NWListener on port 9999 and serves a
small JSON API. The extension's fetch call never leaves the
machine.
If your browser and your app are on the same machine, routing
their conversation through a datacenter is cosplay. A
localhost request completes in under a
millisecond, costs nothing to operate, and cannot be knocked
offline by an outage on a continent you aren't on.
What the extension actually asks for
People are right to be suspicious of extensions. An extension is
a piece of code with a microphone held up to your browser, and
the fix for that is specificity, not reassurance. So here's the
entire permissions block of
manifest.json, with a line about why each one is
there.
activeTab. When you click the toolbar icon, the
extension gets permission to read the tab you just clicked
from, and only that tab. It doesn't follow you around the
rest of your browsing. It's the most user-respecting permission
Chrome offers and I leaned on it hard.
scripting. Required to inject the media scanner --
src/lib/media-detect.js -- into the active tab when
you ask the popup to find downloads. The scanner walks the DOM
for <video>, <audio>, and
<source> tags, and probes known players
(JWPlayer, Plyr, videojs) for their current source. It runs
once, on demand, and returns a list.
contextMenus. Adds the "Download with Veloxar"
right-click item on links, videos, and images, plus a "Send page
to Veloxar" item for the page itself.
storage. Saves two things: the port the desktop app
is on, and the API key returned from pairing. Nothing else.
Host permissions are restricted to
http://localhost/* and
http://127.0.0.1/*. That's it. The extension isn't
allowed to talk to any remote host. It cannot exfiltrate
your browsing data, because its outbound fetch only knows how to
reach 127.0.0.1. The browser enforces that, not me
promising nicely.
The discovery handshake
When the extension starts, it doesn't know whether Veloxar is running. A bad extension would guess and fail silently. A worse one would spin on a timer and burn battery. This one probes a single endpoint and updates a status dot.
The popup's VeloxarAPI.ping() fires a
GET to /api/status on the configured
port. If the response comes back with success: true,
the dot goes green and the tabs light up. If the fetch rejects
with Failed to fetch because nothing's listening,
the dot goes red and the Capture tab shows a clear "open Veloxar
to continue" state instead of pretending to work.
Pairing is a second step. The extension posts to
/api/pair, the app returns an API key (if auth is
enabled), and the extension tucks it into
chrome.storage.local. The trust model is local: if
you can reach the Veloxar process on localhost,
you're already sitting at the machine. I'm defending against
other local processes, not remote attackers, because there
aren't any to defend against.
The Remote API, in seven endpoints
RemoteAPIServer.swift routes seven prefix groups.
The full handler list is in
Sources/Features/RemoteAPI/RemoteAPIServer.swift
if you want to read the code:
GET /api/status-- liveness probe. The handshake.GET /api/version-- app + API version.POST /api/pair-- first-run pairing.GET /api/downloadsand/api/downloads/list-- summary counts and per-item progress for the popup's Downloads tab.POST /api/downloads/pauseAll,/resumeAll, and/{id}/pause|resume|cancel-- control surface.POST /api/linkcollector-- the one that matters. Accepts a JSON array of URLs and hands them to the link collector.GET /api/plugins-- plugin registry stats.
"Send a link" is deliberately the smallest operation I could get away with. No rich metadata, no per-URL options, no package grouping. Just an array of strings:
POST http://localhost:9999/api/linkcollector Content-Type: application/json Authorization: Bearer <api-key> [ "https://example.com/video/abc123", "https://example.com/video/def456" ]
The link collector picks up the URLs, runs them through the crawler pipeline, and the normal Veloxar plumbing takes over. The extension doesn't know or care which plugin will handle the link. It hands off and walks away.
Why popup, not content script
An extension has two places it can run code on a page: a popup (when the user clicks the toolbar icon) or a content script (injected on every page load). They look similar. They are not. A content script runs whether you asked for it or not, on every page the manifest matches, forever. A popup runs when you click it.
Veloxar's content_scripts array is empty. On
purpose. The media scanner lives in the popup flow: you click
the icon, background.js receives a
scan-tab message, and it uses
chrome.scripting.executeScript to inject
media-detect.js into the current tab exactly once.
The scanner runs, returns its list, and that's the entire
lifetime of the injection.
The trade-off is that we don't see media until you ask. An autoscanning content script could pre-warm the list, but it would also be watching you across every site you visit, including the ones where you'd rather it didn't. I picked the conservative side. The popup finishes scanning before you can read the page title; nobody has complained about the latency.
Firefox, honestly
Manifest v3 is cross-browser in theory. In practice, Firefox's
v3 implementation has enough quirks around service workers and
host_permissions that I haven't shipped a Firefox
build yet. The Chromium build (Chrome, Edge, Brave, Arc,
Vivaldi) works today. A Firefox port is on the list, not in the
bag. I'm not going to pretend the checkbox is ticked until it
actually is.
From page to queue
You're on a page with a dozen links you want. You click the Veloxar icon. The popup shows what it found. You hit "Send all to Veloxar." The dot stays green, the popup closes, and the desktop queue grows by twelve items before you've switched windows.
That's the whole feature. What's interesting is what isn't there: no cloud roundtrip, no sign-in, no sync service, no background page scanning, no outbound traffic leaving your machine. One click, one local POST, one growing queue. The boring solution turned out to be the right one.