Nativefier: what it does and where it breaks down

Nativefier keeps turning up as the answer to a small, persistent problem: a web app that gets used every hour lives in a browser tab, and finding that tab costs a few seconds every time. The pitch is one command long. Point it at a URL, get a Mac application with its own icon in the Dock. What the search results rarely cover is what the resulting application actually contains, what condition the project is in, and which parts of a modern web app quietly stop working once wrapped. The figures below come from builds made on a Mac on 12 September 2026, not from the documentation.

What one command actually produces

Running the tool against a URL produces a directory named after the site and the target platform, containing a normal looking .app bundle. The bundle is not a shortcut and not a pointer to an installed browser. It is a complete copy of a browser engine with one URL baked into it.

Measured on disk, a build for a single plain page came to 205 MB. A second build for a different site came to the same 205 MB, which makes sense: almost all of that weight is the engine, and the site specific part is a few kilobytes of configuration. Ten wrapped sites means ten copies of the engine.

Inside the bundle, Contents/Resources/app/nativefier.json records exactly what was decided at build time. A build with no options set produced these values:

"targetUrl": "https://example.com/",
"electronVersionUsed": "25.7.0",
"arch": "arm64",
"width": 1280,
"height": 800,
"zoom": 1,
"singleInstance": false,
"widevine": false,
"disableOldBuildWarning": false

The bundle identifier is generated rather than chosen, in the form com.electron.nativefier.<site>-nativefier-<hash>. The window size, the zoom level and the target URL are fixed inside the bundle at the moment of the build. Changing any of them later means building again, because there is no settings screen in the finished app.

The condition the project is in

The public repository at github.com/nativefier/nativefier is marked archived, which makes it read only. Its last push was 29 September 2023. The last release on the package registry is version 52.0.0, published 25 August 2023. The 258 open issues that existed when the archive happened are still there and cannot receive new replies.

The tool says as much itself. A build run prints this before it starts work:

Hi! Nativefier is minimally maintained these days, and needs more hands. If you have the time & motivation, help with bugfixes and maintenance is VERY welcome. Source: github.com

None of that means the tool is broken. Installing version 52.0.0 on Node 24.12.0 with npm 11.6.2 on 12 September 2026 completed normally, pulling in 674 packages, and the build that followed produced a working bundle. Archived means frozen, not dead. It does mean that anything which changes underneath the tool, whether that is macOS, a site's login flow, or a security advisory in a dependency, will not be answered by a new release.

One consequence shows up during installation. The packaging library the project depends on, electron-packager at version 17, now carries a deprecation notice on the registry telling installers to move to @electron/packager. The rename happened after the archive, so the pinned dependency stayed on the old name.

Installing it, and what the install reports

The documented requirements are modest. The project README asks for macOS 10.13 or later, Node 16.9 or later and npm 7.10 or later, while the published package metadata raises that slightly to Node 16.16.0 and npm 8.11.0. Either way, a current Mac clears the bar comfortably.

Two optional pieces change what the tool can do. ImageMagick or GraphicsMagick is what converts a site's icon into the format a Mac bundle needs, so without one of them installed the icon step has nothing to work with. Wine is what allows a Mac to build a Windows executable, since the tool can target Windows and Linux as well as macOS from the same command. A container image is also published for people who would rather not install any of that on the machine itself.

The install itself is where the age of the project becomes visible in a way that matters. A clean install of version 52.0.0 on 12 September 2026 pulled in 674 packages and finished without error. The package manager then reported 30 security advisories against that dependency tree, of which 20 were rated high and 2 critical. Those advisories are against build time tooling, not against the finished app, which is a real distinction and not a dismissal: a dependency tree that has been frozen since 2023 accumulates advisories simply by standing still, and the number will keep rising rather than falling.

That figure is worth knowing before the tool goes onto a work machine, because in some organisations an install that reports critical advisories is a policy decision rather than a technical one. The two standard responses, running an automatic fix or upgrading to a patched release, are both unavailable here. The dependency versions are pinned by a lockfile shipped inside the package, and there is no later release to move to.

The browser inside is fixed at the moment of the build

This is the property that decides most of what follows. The version of the engine is a constant compiled into the tool. Version 52.0.0 sets its default to Electron 25.7.0, which corresponds to Chromium 114.0.5735.289. A bundle built today therefore carries a browser engine released in 2023.

For comparison, the current stable Electron release is 44.3.0, published 8 September 2026, built on Chromium 152.0.7977.78. The Electron project states its support window plainly:

Electron's official support policy is the latest 3 stable releases. Source: electronjs.org

Version 25 left that window in December 2023. A newer engine can be requested at build time with the -e flag, which shifts the problem rather than removing it, since the chosen version is still frozen the moment the bundle is written.

The authors anticipated this. Every built app checks its own build date on launch, and after 90 days it shows a dialog titled "Old build detected" carrying this text:

This app was built a long time ago. Nativefier uses the Chrome browser (through Electron), and it is insecure to keep using an old version of it. Please upgrade Nativefier and rebuild this app. Source: github.com

The dialog can be suppressed with a flag whose name says what the authors thought of that choice. The honest reading is that the tool expects to be rerun roughly four times a year for each app.

What the wrapper adds that a browser cannot

A wrapped app is not simply a tab with the furniture removed. It runs on its own engine copy, which means its own cookie jar and its own storage. Signing out in the browser does not sign out the app, and a browser profile reset does not touch it. For a second account on the same service, that separation is the whole point.

The command line options cover more ground than most readers expect. --internal-urls takes a regular expression deciding which addresses stay inside the window, with --strict-internal-urls and --block-external-urls tightening that further. --inject adds custom CSS or JavaScript at load time. --single-instance stops a second copy opening. --tray puts it in the menu bar, --always-on-top keeps it above other windows, and --global-shortcuts binds keys that work while the app is in the background. Proxy rules, basic authentication credentials, a fixed language, disk cache size and developer tools access all have their own flags.

There is also a quieter default worth knowing. Unless --user-agent-honest is passed, the app strips the Electron token and its own name out of the user agent string before any request goes out. A site therefore sees a plain Chrome identifier, with the version number matching the engine inside, currently 114.

The three routes side by side

Command line wrapper Install from the browser Paid Mac app
Engine own copy, fixed at build the browser's, updates with it own copy, updated by the vendor
Session and cookies separate from the browser shared with that browser profile separate
Disk per app 205 MB measured a few hundred kilobytes varies by product
Signed and notarized no, ad hoc signature inherits the browser's status yes, as shipped
Updating the engine rebuild by hand happens with the browser vendor update
Price 0, MIT licence 0 from $39.99 for Coherence X6 or Unite Pro
Extensions not available the profile's extensions apply varies by product

The table is not a ranking. It is a statement of which properties travel together. Free and separate and self contained also means unsigned and unattended. Free and updating and extension aware also means tied to a browser profile.

The four places it runs out

Identity. The finished bundle carries an ad hoc signature with no team identifier, which is what building without a developer account produces. On the test build, codesign reported Signature=adhoc and TeamIdentifier=not set, and the Gatekeeper assessment tool refused it outright. A bundle built on the same Mac that runs it has no quarantine attribute and opens without argument. Move it to another Mac by download or AirDrop and quarantine applies, at which point Apple's documented route is the only way through.

Sign in. Services that treat embedded browsers as a security risk will refuse the login form. Google states the rule directly:

Google might stop sign-ins from browsers that: Don't support JavaScript or have JavaScript turned off. Have unsecure or unsupported extensions added. Are being controlled through software automation rather than a human. Are embedded in a different application. Source: support.google.com

Protected video. Streaming services that use content protection will not play, because the decryption module is not part of a standard engine build. There is a --widevine flag, and it works by requesting a differently suffixed engine release from a third party rather than by enabling something already present.

Naming and icons. Both test builds took the app name from what the page advertises about itself. One of them produced a name over sixty characters long, which then became the name of the folder, the bundle and the Dock entry. Both builds also fell back to the generic engine icon, because neither page offered an icon the tool could convert. Passing --name and --icon explicitly is less an optimisation than a requirement.

What to change first

Build one app by hand, note the date, and put a reminder 90 days out. If that reminder feels like a chore rather than maintenance, the wrapping approach is right and the manual build is the wrong half of it, in which case compare what a maintained tool covers on the Features page and check whether the service is already handled in the Supported services list. Kagemusha exists for the case where the wrapped app should keep working without being rebuilt by hand every quarter.

Frequently asked questions

Is Nativefier still safe to use in 2026?

The tool installs and builds normally, but the repository has been archived since September 2023 and the last release is version 52.0.0 from August 2023. The engine it defaults to, Chromium 114, left its support window in December 2023. Treat a built app as something that needs rebuilding on a schedule rather than something that maintains itself.

How much disk space does each wrapped app take?

A build measured on 12 September 2026 came to 205 MB for a single site, and a second build of a different site came to the same figure. Nearly all of that is the browser engine, which is not shared between apps, so five wrapped sites occupy roughly a gigabyte.

Why does the built app open with a generic icon and a strange name?

The tool reads the name and the icon from the page itself. If the page advertises a long descriptive title, that whole string becomes the app name, and if no convertible icon is found the generic engine icon is used. Passing --name and --icon at build time avoids both.

Can a newer version of Chromium be used instead of 114?

Yes. The -e flag accepts a specific engine version at build time, and a newer one will be downloaded and packaged. The version is still frozen into that bundle, so the app does not gain the ability to update itself, and the 90 day old build warning still fires based on when the build was made.

Back to all posts