How WebCatalog Uses APFS Clones to Cut Mac App Disk Usage by Up to 8x

The WebCatalog desktop app now uses APFS clones on macOS to dramatically reduce disk usage. By storing identical Electron and Photon data only once, additional apps typically add just 1–2 MB of physical storage instead of around 320 MB.

September 23, 2026

Nguyen Tran · Software Engineer

How WebCatalog Uses APFS Clones to Cut Mac App Disk Usage by Up to 8x

Each app you create with the WebCatalog desktop app used to take around 320 MB of disk space on macOS. That isn't unusual for an Electron-based app, but WebCatalog is designed for people who use many web apps as desktop apps. Install ten of them and they could consume more than 3 GB, even though most of the data inside those apps was exactly the same.

We recently changed how the WebCatalog desktop app builds apps on macOS. The first app now uses around 340 MB of physical disk space, including a prepared copy of the app engine kept locally. After that, each additional app typically adds only 1–2 MB of real disk usage. In our testing, ten apps went from more than 3 GB to around 360 MB.

We did this using a feature already built into macOS: APFS clones. The interesting part wasn't simply cloning files. It was making cloning work while keeping each app independent, correctly code-signed, and functionally equivalent to one built using the old process.

Why every app used another 320 MB

The WebCatalog desktop app turns websites into standalone desktop apps. Every app you create runs on Photon, our app engine built on Electron. On macOS, each one is a normal .app bundle containing Electron (Chromium and Node.js), Photon, and the files for that specific app.

Take two apps, for example Slack and Discord. Their names, icons, bundle identifiers, and configuration differ, but the large Electron framework and most of Photon are identical.

Until now, each app was built as a completely separate copy.

Slack.app
  Electron
  Photon
  Slack-specific files

Discord.app
  Electron
  Photon
  Discord-specific files

The Electron framework and Photon might be byte-for-byte identical in both apps, but macOS still stored another physical copy for every app. Ten apps therefore meant roughly ten copies of almost the same 320 MB application bundle.

That architecture did have one property we wanted to preserve: every app was fully independent. Deleting one couldn't affect another, and installed apps didn't depend on the WebCatalog desktop app continuing to exist on the system.

What we wanted to eliminate was the unnecessary duplication underneath them.

APFS already had the primitive we needed

Modern Macs use Apple's APFS file system. APFS supports cloning, a copy-on-write mechanism that lets two independent files share the same physical data until one of them changes.

Imagine copying a 300 MB file. With a normal copy, macOS writes another 300 MB to disk, so the two files consume around 600 MB in total.

With an APFS clone, the new file still looks and behaves like a complete 300 MB file, but initially it points to the same physical blocks as the original.

File A ─────┐
            ├── shared physical blocks
File B ─────┘

If part of File B changes later, APFS writes new blocks only for the changed data. Everything that remains identical can continue sharing the original blocks.

File A ───────── shared blocks

File B ───────── shared blocks
       └──────── changed blocks

From the application's point of view, File A and File B are separate files. From the SSD's point of view, identical data only needs to be stored once.

That is almost exactly the behavior we needed.

Building apps from a common base

The WebCatalog desktop app now prepares a base for each combination of Electron and Photon versions. The Photon base app contains the parts that are identical across apps, including Electron, Photon, the framework structure, and the common signatures.

When the desktop app creates another app using the same versions, it no longer extracts and builds another complete copy from scratch. Instead, it creates an APFS clone of the Photon base app and customizes only the parts that need to be different.

Those include the app name, icon, bundle identifier, settings, executable names, build identifier, and other app-specific metadata.

Because most of the bundle remains unchanged, APFS continues sharing the physical blocks that contain Electron and Photon. Only the relatively small amount of app-specific data consumes new space.

Why not just share Electron?

A more obvious approach would be to install Electron once and make every app point to it.

We considered that, but it would fundamentally change the reliability model. If the shared Electron installation disappeared, every app depending on it could stop working. A cache cleaner could remove it, uninstalling the WebCatalog desktop app could remove it, and moving or restoring an individual app would become more complicated.

It would also require tracking which installed apps depend on which runtime versions so that old versions could be cleaned up safely.

macOS code signing creates another problem. Strict signature verification rejects symlinks that point outside the app bundle.

APFS clones give us the useful part of sharing without introducing that dependency. Installed apps can share physical disk blocks while remaining complete, independent application bundles.

Deleting the Photon base app doesn't break apps created from it. Deleting one installed app doesn't affect another. The filesystem handles the sharing while the application architecture remains independent.

Code signing almost eliminated the savings

Cloning the app was only part of the problem. macOS applications also need to be code-signed.

Our old build pipeline deeply re-signed each application bundle after customization. For a normal copy, that is fine. With copy-on-write storage, however, modifying a large binary can cause APFS to allocate new physical blocks for it.

During development, we measured re-signing the Electron framework adding roughly 194 MB of physical storage per app. We had successfully avoided copying Electron during app creation, only to duplicate much of it again during signing.

So the signing process had to change as well.

The large common framework is now signed as part of the Photon base app. When the desktop app clones that base, we avoid modifying those large shared binaries and re-sign only the smaller parts that actually need to differ between apps.

Once the app is complete, we run strict signature verification against the finished bundle to make sure everything remains valid.

This lets us keep both macOS's code-signing guarantees and the storage savings from APFS.

When asking Node.js to clone didn't actually clone

There was another unexpected problem: performing the clone itself.

Node.js exposes copy flags intended to request copy-on-write behavior, including COPYFILE_FICLONE and COPYFILE_FICLONE_FORCE. On paper, those sounded like exactly the APIs we needed.

In our testing on Node.js 24, we copied the same 288 MB Electron application using several methods and measured how much additional physical disk space each operation consumed:

fs.cpSync                              +288 MB
fs.cpSync + COPYFILE_FICLONE           +288 MB
fs.cpSync + COPYFILE_FICLONE_FORCE     +288 MB
/bin/cp -c -R                          ~0 MB

Both Node.js clone modes still produced a full physical copy in our test, and even the FORCE variant didn't report an error when the expected cloning behavior didn't occur.

The native macOS cp -c operation behaved as expected, so the WebCatalog desktop app uses that mechanism directly.

It was also a useful reminder that filesystem optimizations should be verified by measuring the filesystem itself. Calling an API that requests copy-on-write doesn't necessarily mean the resulting files actually share physical storage.

Making the optimization safe to fail

Saving disk space is an optimization. Successfully installing an app is not.

We designed the new pipeline so that cloning can fail without breaking app installation. If preparing the Photon base app fails, if the cached base is damaged, if cloning fails, or if signature verification doesn't pass, the desktop app falls back to the previous build process using a full extraction and full signing.

The worst case is therefore the same disk usage as before, not a failed installation.

We also had to account for concurrency. A Photon base app is first prepared in a temporary directory and only moved into its final location once it's complete. That way, two app builds happening at the same time cannot accidentally observe a half-built base.

Older bases can be removed safely too. An installed APFS clone doesn't depend on the original base continuing to exist. If the base is deleted, the clone keeps the physical blocks it still uses.

This works on APFS, the default file system on every modern Mac. If your apps live on a disk that can't clone, such as an external HFS+ or exFAT drive, the WebCatalog desktop app falls back to a regular copy, so the apps work as before but don't save space. Windows and Linux are unchanged for now.

Logical size and physical size are not the same thing

One slightly confusing side effect is that Finder may still report each app as being around 320 MB.

That number represents the app's logical size. The app really does contain roughly 320 MB worth of files, and if those files were copied somewhere without cloning, that is roughly how much data would need to be written.

What changed is the physical size, or how many unique blocks those files actually occupy on the disk.

If two apps contain the same 300 MB framework and APFS allows them to share the same underlying blocks, each app can logically contain 300 MB while the second one adds almost no new physical data.

Finder's Get Info view and tools such as du don't necessarily make this sharing visible. The savings are most noticeable in the amount of free space actually remaining on the disk.

We verified this with seven real apps: Discord, Facebook, Instagram, Messenger, TikTok, and two custom apps. Built this way, they saved about 1.9 GB of disk space compared with the old build process.

We also checked the underlying physical disk offsets and confirmed that the apps shared their common Electron and Photon data at the block level. An app created using the old build process shared none of those blocks, giving us a useful comparison.

The result

For someone who creates only one app with the WebCatalog desktop app, the difference is small. The first app actually uses slightly more disk space than before because the desktop app also keeps the Photon base app used to create subsequent clones.

The benefit grows quickly after that.

Before

1 app       ~320 MB
10 apps     >3 GB

With APFS cloning:

After

1 app       ~340 MB
10 apps     ~360 MB

After the initial base is created, each additional app typically adds only 1–2 MB of physical disk usage.

The important part is that we achieved this without introducing a shared runtime dependency. Each app remains a normal, self-contained macOS application, while APFS stores the identical Electron and Photon data only once. With around ten apps installed, that can reduce actual disk usage by more than eight times.

This is available in the latest version of the WebCatalog desktop app on macOS. There's nothing to turn on: new apps use it automatically, and apps you already have shrink the next time they update.