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.
Every profile is drawn from one real computer, not from separate listsIn Mosaic: Machines that exist. GPU, screen, CPU and fonts from one real device. 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.
How it works: Machines that exist
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 covers the other class: values that agree with each other because they come from real hardware. The browser fingerprint entry lists what a site actually reads, and canvas fingerprinting covers the surface people ask about most.





