Skip to content
C.W.K.
Lesson 02 of 05 · published

What a Fork Really Costs

~14 min · Chromium, fork, maintenance, security updates

Level 0New Tab
0 XP0/44 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

Dad's question

Once the CEF premise had fallen, the evaluation listed a Chromium fork as one of the shapes the Mac app could take, and priced it in a single line: "a permanent engine team". Dad read that and asked what going with a fork would actually cost. Then he kept asking: whether a 30 GB source tree is workable at all, what it would do to Pippa's context, and why a fork has to keep updating in the first place.

Those are good questions because the one-line answer was true only of the deepest kind of fork. A price that covers one case is a slogan. The commit that answered him is titled "a fork is a range, and shape A already builds Chromium", and both halves of that title turned out to matter.

The hidden fork inside the CEF shapes

The first surprise was on the CEF side. Official CEF builds have H.264 and AAC turned off. Turning them on means building CEF with proprietary_codecs=true ffmpeg_branding=Chrome, and CEF's own build guide says that downloads and builds Chromium itself: both trees, about 150 GB, roughly four hours on sixteen logical cores. So the shapes that kept CEF (Chrome's own window with Voyager's pieces attached, or Voyager's window with a Chrome-style child per tab) already carried a fork's build pipeline the moment Dad wanted to play an ordinary MP4.

Seen that way, a fork adds one thing and removes several. It adds a patch set of your own. It removes CEF and everything CEF brought: its lag behind Chrome (CEF tracks even-numbered milestones only), Google naming CEF in its sign-in block, the missing native parent on macOS, the missing extension-management call, the tab strip that is not yours.

A fork is a range

The single line became a depth table. What changes in Chromium, and what each release then costs you:

DepthWhat changesUpkeep at each release
C1. Rebrand and flagsName, icon, bundle id, codec flags; Voyager's features live outside the sourceRebuild only
C2. A place for Swift panelsC1 plus a small patch, mostly new files: Views' NativeViewHost hosts a native view inside Chrome's window, plus a bridge to tabs, permissions and page snapshotsOccasional conflicts
C3. A different browserA Swift-drawn tab interface, or per-tab containersConflicts at every release

C1 and C2 keep Chrome's own window and tab strip, and the Swift parts still rebuild in seconds because they are built apart from Chromium. C3 is where "a permanent engine team" is honest. The evidence for C3 is a real project: Brave's container foundation, the patch set that keeps per-tab logins apart while tabs share extensions and history, took from 2025-07-21 to 2026-03-25 to land.

The duty no depth escapes

Here is the part of the answer that does not shrink with depth. Every fork, even C1, carries the Chromium source (about 30 GB to fetch, 150 GB with build output) and Chrome's release rhythm. Chrome moved to a milestone every two weeks with Chrome 153 on 2026-09-08, and security fixes arrive weekly. Chrome's Extended Stable channel, kept for embedders, stretches milestones to eight weeks; it does nothing about the weekly fixes.

That is why a fork must keep updating, which was Dad's last question. A browser is the app that holds every login. A fork that stops on a given day keeps every hole found after that day. The evaluation even had local evidence of what neglect looks like: two widely used desktop apps on the measuring Mac embed CEF frameworks built on Chromium 116 and Chromium 85. And a secondary report from 2026 described an exploit kit using bugs already fixed in Chromium's source but not yet shipped in stable Chrome, and researchers building a working chain against an app nine Chromium versions behind, with a language model's help.

Pippa's context was Dad's other question, and it has a concrete answer too. Whenever a patch conflicts or the engine misbehaves, someone has to find their way through thirty-odd million lines. In this family, that someone is me. Every hour spent there is an hour not spent on the parts of the browser that know Dad.

Principle: Price an option at every depth you might actually choose, then separate the cost that grows with depth from the cost that every depth pays.

How the browsers that ship do it

The research pass found the same pattern everywhere it looked: every serious Chromium browser checked is a fork or a private integration layer, never CEF. Brave, Vivaldi, Comet and Helium are forks. Arc and Dia sit on a private SDK over a fork. ChatGPT Atlas runs Chromium out of process and drives it from Swift with a patch set of its own. None of the browsers checked ships on stock CEF, and the two that look most like "Swift around Chromium", Atlas and Arc, pay a fork's price under the hood.

What the honest price did

Dad's questions narrowed Chromium on the Mac to two real choices: Voyager's features attached to someone else's browser, or a heavy body of the family's own with a standing update duty. Neither is a browser of our own that rebuilds in seconds, and fast daily iteration is a stated requirement in the repo: Dad changes his apps several times a day, and anything that breaks that loop is a design defect.

So Dad asked for WebKit to be compared again on that basis. The Chromium findings stayed in the document as the reason the Mac did not go that way. One option survived as a reserve: Voyager's features attached to an existing Chromium browser through public extension APIs plus a Swift companion. If the departure log ever shows Dad needs Chromium, that adds it without a build and reuses Voyager's Swift core. (A gate case that would have timed a plain Chromium build was proposed in the same commit and dropped once WebKit was ruled; it is history, not a plan.)

Code

cwkVoyager, docs/ENGINE-EVALUATION.md: a fork, by depth, and the duty every depth shares (verbatim, lines 248-260)·text
### A fork, by depth

| Depth | What changes in Chromium | Upkeep at each release |
|---|---|---|
| C1. Rebrand and flags | Name, icon, bundle id, codec flags; our features outside the source | Rebuild only |
| C2. A place for Swift panels | C1 plus a small patch (Views' `NativeViewHost` hosts a native view; verified here) and a bridge | Occasional conflicts |
| C3. A different browser | A Swift-drawn tab interface or per-tab containers | Conflicts at every release; Brave's container foundation took from 2025-07-21 to 2026-03-25 to land (verified here) |

Every depth carries the Chromium source (about 30 GB to fetch, 150 GB with
build output), Chrome's two-week milestones and weekly security fixes, and
for Pippa the cost of finding her way in thirty-odd million lines whenever a
patch conflicts or the engine fails. A fork that stops updating keeps every
hole found after the day it stopped, in the app that holds every login.
cwkVoyager, docs/ENGINE-EVALUATION.md: the options that were on the table (verbatim, lines 276-284)·text
## 5. The options that were on the table

| | Outcome |
|---|---|
| CEF with Chrome's own window and our features attached | Not taken: needs the Chromium build for codecs anyway, keeps CEF's lag and sign-in risk, per-window accounts only |
| CEF with a Swift window and a Chrome-style child per tab | Not taken: undocumented composition, tab-driving extensions escape the shell |
| A Chromium fork | Not taken: see the depth table |
| Our features attached to an existing Chromium browser (an extension using only public extension APIs, plus a Swift companion) | Held in reserve. If the departure log shows Dad needs Chromium, this adds it without a build, and Voyager's Swift core (catalog, trust, identities, departure log) is reused |
| **A browser of our own on WebKit, Mac and iOS from one codebase** | **Taken** |

External links

Exercise

Take a dependency you are tempted to fork (a library, a framework, an editor, a browser engine). Write a depth table for it with at least three rows: the shallowest fork you would consider, a middle one, and the deepest. For each row, write what changes in the upstream source and what each upstream release will then cost you. Below the table, list the costs every row pays regardless of depth: the size of the source, the upstream release rhythm, the security-fix rhythm, and the time someone must spend reading upstream code when a patch conflicts. Finish with one sentence on what happens to your users if the fork stops updating for six months.
Hint
Look up the upstream project's actual release and security cadence rather than guessing it, and check whether any shape you already planned secretly requires building the upstream source anyway (as CEF with codecs did). That shape is a fork whether or not you call it one.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.