# Why we built our own Chromium

> Mosaic changes fingerprint values in C++ inside its own engine. Three measured differences between Chrome and plain Chromium explain why that matters.

Source: https://mosaicbrowser.com/blog/why-we-built-our-own-chromium

## Why we built our own Chromium instead of injecting JavaScript

Mosaic changes fingerprint values in C++ inside its own engine. Three measured differences between Chrome and plain Chromium explain why that matters.

![Values change in C++, not in the page, beside a screenshot: mosaic settings showing the installed Tesseract Chrome engine and its version](https://mosaicbrowser.com/covers/why-we-built-our-own-chromium.webp)

Mosaic ships its own browser engine, Tesseract Chrome, because a fingerprint changed by a script in the page cannot be made to agree with itself everywhere a site looks. A fingerprint changed in C++ can. This post is the reasoning, and three measurements that turned out to matter more than the reasoning.

## Where a spoof lives decides who can see it

The usual way to give a browser a different fingerprint is to inject JavaScript before the page loads and overwrite what the page reads: `navigator.hardwareConcurrency`, the WebGL renderer string, the canvas readback. It works in the page realm. Then a site opens a dedicated worker, or an iframe, or asks WebGPU from a worker, and gets the real machine, because the injection never ran there.

Overwritten functions also look overwritten. A native function and a replacement written in JavaScript differ in small ways a script can test, and detectors test them. Worse, two spoofs of one value compose into something neither side predicted. A consistency scanner does not need to know the true value; it only needs two answers that disagree.

Tesseract Chrome is stock Chromium source with more than sixty patches applied, and the patches move values inside the engine. Canvas noise is added where image data is read back. The timezone, the screen geometry, the GPU strings and the audio latency each have a patch of their own, in the file that produces the value. Every realm asks the same C++ and gets the same answer, so there is nothing to catch disagreeing. That is also why Mosaic has a rule against spoofing anything in JavaScript on its own engine: a script layered on top of a patch is exactly the two-spoof problem again.

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Machines that exist](https://mosaicbrowser.com/features/real-fingerprints)

## A Chromium build is not a Chrome build

The less obvious reason to own the engine is that plain Chromium is not Chrome, and the difference is measurable from a page. Almost every anti-detect browser claims to be Google Chrome in its User-Agent. If the engine underneath behaves like an unbranded Chromium, the claim and the behavior disagree.

We measured three such differences against Google Chrome on the same machine.

### Field trials

A non-branded Chromium compiles in a file called `fieldtrial_testing_config.json` and turns its experiments on at every launch. Google Chrome does not run that file. Compared with Chrome 153 on the same Mac, that was twenty differences in the API surface a page can enumerate. There was no `navigator.runAdAuction`, no `Document.browsingTopics` and no `window.XSLTProcessor`, and `window.ModelContext` and `window.WebMCPEvent` were present, which Chrome does not have.

An API a page finds on you and not on Chrome is a positive identification, not an ambiguity. One switch, `--disable-field-trial-config`, moved all twenty back, and a check in our build now fails if it ever goes missing.

### Speech voices

`speechSynthesis.getVoices()` returns 199 voices on branded Chrome and 180 on any unbranded build. The 19 missing ones are Google's network voices, supplied by a component extension that only ships when Chromium is compiled as Chrome. One call reads the whole list, so a browser claiming Chrome with 180 voices identifies itself. We had first excused this field in our comparison script because the list loads asynchronously and the probe read 0 in both browsers. The probe was the bug. Patch `0145-branded-tts-voices` restores the 19 voices where the extension's own would arrive.

### Widevine

This one has no engine fix, so Mosaic turns it off. The Widevine module that plays protected video encrypts its client ID, which Google calls privacy mode, only when the host browser carries Google's signatures. Nothing we build can carry the second of the two. Without it, the first license request carries the device certificate in the clear: 1,704 bytes, where branded Chrome sends 2. That certificate is stable per install, so it would tie every profile on one machine together. Widevine stays off unless a profile asks for it.

## The control we should have run first

Four days went into one detector signal on the assumption that one of our patches caused it. Google's own unbranded build, Chrome for Testing, unpatched, earned the identical verdict. One 90-second run would have ruled out the whole series on day one. Now the first question about any finding is whether a stock Chromium already does it.

Owning the engine also makes experiments cheap. On our build machine, changing one patch and relinking takes one to two minutes. A move to a new Chromium major took 93 minutes. So when a site starts reading something new, the loop from hypothesis to verdict is minutes, which is the practical case for owning the engine.

None of this makes a browser undetectable, and we do not claim it does. It removes the class of mistakes where the browser contradicts itself. [Machines that exist](https://mosaicbrowser.com/features/real-fingerprints) covers the other class: values that agree with each other because they come from real hardware. The [browser fingerprint](https://mosaicbrowser.com/glossary/browser-fingerprint) entry lists what a site actually reads, and [canvas fingerprinting](https://mosaicbrowser.com/glossary/canvas-fingerprinting) covers the surface people ask about most.

## Related

[Introducing Mosaic, an anti-detect browser that lives on your machine](https://mosaicbrowser.com/blog/introducing-mosaic): Mosaic runs its own Chromium, draws each profile from a real machine and matches it to the proxy exit. Profiles stay on disk. One plan, no per-profile fees.

[Machines that exist: fingerprints drawn from real hardware](https://mosaicbrowser.com/features/real-fingerprints): Mosaic draws each profile's GPU, screen, CPU, memory and fonts from one real device, so the parts of a fingerprint agree with each other and with the host.

[Browser fingerprint: what a site can read about your machine](https://mosaicbrowser.com/glossary/browser-fingerprint): A browser fingerprint is the set of values a site reads about your browser and computer, which together recognize you without cookies. What goes into one.

[Canvas fingerprinting: how a drawing identifies your computer](https://mosaicbrowser.com/glossary/canvas-fingerprinting): Canvas fingerprinting draws hidden text and shapes, reads the pixels back and hashes them. Small rendering differences make the hash a mark of your machine.

[The best anti-detect browsers, compared on the same criteria](https://mosaicbrowser.com/compare/best-anti-detect-browsers): Seven anti-detect browsers on one table: free plan, entry price, what they bill by, teams, mobile and automation, from each vendor's own page in November 2026.







## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per profile. Free holds 3 profiles. Pro is $49 a month for any number.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
