Web app to desktop app: choosing the route on a Mac

Somewhere in the browser there are five or six sites that function as software. A ticketing system, a design tool, an admin console, a mail client, a chat room. They are open every working day, they hold state, and they are indistinguishable from the news article and the shopping cart sitting next to them in the tab strip. Converting one of them into a desktop app is a small piece of work. Choosing which conversion route to use is the part that decides whether the result still works in two years.

The real variable is who maintains the result

Every route produces the same visible outcome: an icon in the Dock, a window without a tab strip, a thing that appears in Command Tab. The routes differ in something that is invisible on day one, which is who is responsible for keeping the window running when the browser engine underneath it changes.

There are four owners available. The vendor of the service, if a desktop build exists. The browser maker, if the browser has an install feature. The person doing the converting, if a custom app gets built. Or a generator that tracks whatever browser is already installed on the machine.

Ranking those by effort is the wrong first move. Ranking them by what happens after a Chromium security update is the right one, because that update arrives every few weeks regardless of which route was chosen. A conversion that requires a human to rebuild it is a conversion with a maintenance schedule attached.

Route one, the vendor's own build

Before any tool gets involved, the first question is whether the service already ships a desktop client. Many do, and using it removes the whole problem.

Two things are worth checking before committing to it. The first is the minimum operating system, which is where these apps quietly diverge from the website. A service that works in any browser on a 2015 iMac may require a recent macOS for its installed client, and the requirement rises over time. The second is what the client actually is. A large share of vendor desktop apps are web views with a shell around them, which means the feature set matches the website exactly and the only difference is the frame.

That second point cuts both ways. If a vendor app is a wrapper, then a self made wrapper of the same site is not a downgrade in capability. If the vendor app is genuinely native, offline sync, local file indexing and system integrations may exist that no wrapper can reproduce, and the vendor app wins outright.

Route two, what the browser already does

Chrome has a built in path and documents it in its help center. The route is the More menu, then Cast, save and share, then Install page as app. The result is a windowed instance of the site with its own icon.

A web app is an app built for the web that you can access on any device. You can use web apps to have a website work as an app and access it on your computer or mobile devices through the launcher or home screen. Source: support.google.com

Safari has the equivalent, added in macOS Sonoma, through File and then Add to Dock. Apple's description of the result is more specific about isolation.

A web app functions independently of Safari. It shares no browsing history, cookies, website data, or settings with Safari. Source: support.apple.com

Both are free, take under a minute, and are maintained by the browser vendor, which is the strongest argument for trying them first. The limits show up on the second or third conversion. Chrome's version inherits the profile it was created in, so ten apps made from one profile share one login state and one extension set. Safari's version isolates cleanly but runs WebKit, so Chrome Web Store extensions do not apply, and any site that misbehaves outside Chromium misbehaves here too.

Route three, building the app

The third route is writing an application. Two frameworks dominate, and they differ in a way that matters for a wrapper.

Electron ships its own engine.

Electron is a framework for building desktop applications using JavaScript, HTML, and CSS. By embedding Chromium and Node.js into its binary, Electron allows you to maintain one JavaScript codebase and create cross-platform apps that work on Windows, macOS, and Linux. Source: electronjs.org

Tauri takes the opposite approach and borrows the engine from the operating system.

Tauri apps take advantage of the web view already available on every user's system. Source: tauri.app

For a real product, either choice is defensible. For wrapping a website that is already working, both introduce the same liability: the finished bundle is frozen at the moment it was built. Its embedded engine ages, or the system webview moves and the app has to be tested against it, and either way a person has to notice.

The clearest evidence for that liability is Nativefier, the best known one command wrapper generator. It has more than 35,000 stars on GitHub and it is archived. The repository has been read only since September 2023, with the description still reading make any web page a desktop application. Apps generated by it keep launching, on the Chromium version that was current when they were built. That is the shape of the risk in every self built wrapper: it does not break on the day it is abandoned, it breaks quietly, later, when a site starts requiring something the frozen engine does not have.

Route four, a generator that follows the installed browser

The fourth route exists because of exactly that failure mode. Instead of bundling an engine or freezing a build, the generated app points at a Chromium based browser already installed on the Mac, through a symbolic link. Updating Chrome, Brave, Edge or Vivaldi updates every app built on it, with no rebuild step.

Two consequences follow. Extensions from the Chrome Web Store work inside the generated windows, per app rather than per machine, which is the single feature no WebKit based route can offer. And each app gets an isolated profile, so two apps made from the same URL hold two independent logins, which is how a work console and a personal account stop colliding. The Features page lists which of those settings are set per app.

Route Engine source Maintenance Extensions Profiles
Vendor desktop app Vendor's choice Vendor Usually none Vendor's login model
Chrome, install page as app Installed Chrome Google Yes, profile wide Shared with the profile
Safari, Add to Dock WebKit Apple Safari extensions Isolated per web app
Electron or Tauri build Bundled or system The builder Only if coded Only if coded
Site to app generator Installed browser Browser vendor Yes, per app Isolated per app

Signing, Gatekeeper and the costs nobody counts

Three costs sit outside the feature comparison and only appear after the conversion.

The first is Gatekeeper. On macOS, an app that arrives from the internet carries a quarantine flag, and the system checks it for a Developer ID signature and a notarization ticket from Apple before the first launch. A bundle built locally on the same Mac does not go through that check, which is why a self built wrapper opens fine on the machine that produced it and gets stopped on a colleague's machine. Distributing one internally means enrolling in the developer program and notarizing every build, which is a real ongoing task rather than a one time step.

The second is disk and duplication. Isolated profiles are the feature that makes multiple accounts work, and each profile is a real directory holding cookies, cache and extension data. Ten apps means ten profile directories that grow independently. This is not a large cost on a modern disk, but it is not zero, and it explains why a machine with many generated apps benefits from deleting ones that stopped being used rather than keeping them for later.

The third is the sign in tax on day one. Every isolated profile starts empty, so the first launch of each app shows a login screen, including the ones that felt permanently signed in inside the main browser. Tools that support copying a template profile reduce this to a single sign in reused across new apps, and the browser routes avoid it entirely by sharing an existing profile, which is the same reason they cannot isolate anything.

Which web apps are worth converting

Not every tab deserves an icon. A conversion pays off when at least two of these are true, and is mostly noise when only one is.

It is opened more than twice a day

Frequency is what converts saved keystrokes into saved attention. A site opened weekly is faster to reach through a bookmark.

It needs its own login that must not be shared

Two accounts on one service, a client's admin panel, a shared team inbox. Isolation is the one thing a bookmark cannot provide, and it is the strongest single reason to convert.

It sends notifications that should be ranked separately

Once a site has its own app, it appears as its own entry in System Settings under Notifications, with its own alert style, sound and badge. That is how one service gets banners and another gets a silent badge.

It should survive quitting the browser

Restarting a browser with fifty tabs, or closing it at the end of the day, currently takes the tool with it. A separate app decouples the two lifecycles.

It depends on a specific extension

A password manager, a translation extension, a screenshot tool. This requirement immediately eliminates the WebKit route and points at a Chromium based one.

It has an interface that fights the browser chrome

Dashboards, canvases and consoles built for a full window lose real estate to a tab strip and an address bar. Hiding both gives back vertical space on every screen, which is the one visual gain that shows up immediately.

Two of these five conditions is the threshold worth using. A ticketing system opened all day that needs a work login qualifies. A monthly invoice portal does not, no matter how convenient the icon would feel, and a folder of unused apps is its own small mess.

What to change first

Pick the single site opened most often and convert it with the browser's own feature, free, in under a minute, then use it for a week. If the friction that remains is a shared login, a missing extension, or notifications that cannot be separated, move that one site to a per app profile with a tool such as Kagemusha and leave the rest in tabs. The Pricing page shows where the free tier ends, which is the point at which this stops being a free decision.

Frequently asked questions

Is a converted web app faster than the same site in a tab?

Not meaningfully in rendering terms, since the same engine draws the page. What changes is access and attention: one keystroke to reach it, no tab hunting, no accidental closing, and a window whose lifecycle is independent of the browser. Memory use is roughly comparable to running the site as a tab.

Do these apps work offline?

Only as far as the site itself supports it. A wrapper does not add offline storage. Sites that implement service workers keep their offline behaviour inside the app window, and sites that do not will show a connection error exactly as they do in a browser.

Why is Nativefier no longer recommended?

Its repository has been archived and read only since September 2023, so the bundled Chromium in anything it produces does not advance. Existing apps keep launching, but the engine ages against the sites it loads. Routes that follow an installed browser avoid that specific failure.

Can one desktop app hold several services?

Yes with some tools, through a sidebar or a set of tabs opened at launch, which suits a group of services used together such as mail, calendar and drive. The trade off is that services grouped this way share one profile, so anything needing a separate login still needs its own app.

Back to all posts