a mobile UA has a real touch stack
Check id touch-createevent-coherence
What an ordinary browser yields
A mobile UA reports maxTouchPoints > 0 and document.createEvent('TouchEvent') succeeds.
What a detector infers
This check asserts in one direction only: if navigator.userAgent matches iPhone, iPad, iPod or Android, then the environment must also have navigator.maxTouchPoints > 0 and a constructible TouchEvent via document.createEvent('TouchEvent'). It does not assert the converse — touch present therefore UA must be desktop — because that would hard-fail real iPadOS desktop-mode Safari and every touchscreen laptop. The createEvent leg is the load-bearing one: it is gated by the engine's internal event-factory table, not by a navigator binding, so no amount of defineProperty on navigator reaches it. A mobile UA with maxTouchPoints=0 or a non-constructible TouchEvent therefore indicates that the user-agent string was changed without the touch stack behind it. Severity is warn; a desktop UA yields N/A.
How to resolve it
Enable real touch emulation at the engine level rather than only swapping the user-agent string. maxTouchPoints can be overridden from JS, but the event-factory table that governs createEvent('TouchEvent') cannot.
Read in the wild by
Kasada
Kasada's collector reads all three inputs this check uses: `touch_event_check` — a `document.createEvent('TouchEvent')` try/catch — is its own payload slot beside separate `window_max_touch_points` and `iframe_max_touch_points` slots, and one function in the decompiled script combines `/iPhone/.test(navigator.userAgent)`, `navigator.maxTouchPoints <= 0`, and whether `createEvent('TouchEvent')` throws into a single reported `verdict`.
Kasada corpus at C:/Users/pim_d/Downloads/cc/antidetect (provider confirmed: 3.txt `{"x-kpsdk-v":"j-1.2.381","x-kpsdk-ct":...}`; `kpsdk` 35x in 2.txt). Probe slots — probes.txt:298 `touch_event_check`, :157 `iframe_max_touch_points`, :385 `window_max_touch_points`; blog.txt 427-probe dump: `batch 1: fn_131858 -> 24 slots [... 323:touch_event_check(fn_134582) ...]`. Probe body — 2.txt func_011263: `try { _944.efg.document.createEvent("TouchEvent"); return true; } catch {...}` (same at 1.txt func_000b8f via `_7507.lrc.document`). Combined verdict function — 2.txt func_0002c8 (also 1.txt func_0240ef, 3.txt @745822): `r6 = new RegExp("iPhone",""); tmp1009 = r6.test(globalThis.navigator.userAgent);` … `r7 = r4["maxTouchPoints"]; r5 = r7 <= 0;` … `try { globalThis["document"].createEvent("TouchEvent"); _7489 = true; } catch {...}` … `return { verdict: _7490, raw: stringify({tpz, dt}), error: false }` where `dt` = the createEvent success boolean. `maxTouchPoints` appears 10x in 2.txt. Our check: knowledge.ts:589.
CreepJS
CreepJS — an open-source research demo rather than a production detector — records touch support in its screen fingerprint via a `hasTouch()` helper that requires both `'ontouchstart' in window` and a successful `document.createEvent('TouchEvent')` construction; it separately reads `navigator.maxTouchPoints` in its navigator module.
src/screen/index.ts:6-11 — `function hasTouch() { try { return 'ontouchstart' in window && !!document.createEvent('TouchEvent') } catch (err) { return false } }`, consumed at src/screen/index.ts:68 as `touch: hasTouch()` in the screen fingerprint. Separately, src/navigator/index.ts:225-230 reads `navigator.maxTouchPoints`. (github.com/abrahamjuliot/creepjs, master)
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Screen & display
- the outer window fits within the screen
window-boundsThe check asserts only the zoom-invariant bound: window.outerWidth/outerHeight must be non-zero and must fit within the screen. - a non-touch desktop has a fine pointer + hover
pointer-hover-desktopThis check applies only when the UA identifies a desktop platform (Windows, Macintosh, Mac OS X, X11, Linux, CrOS, and not Android/Mobile)… - maxTouchPoints coheres with pointer media
touch-pointer-coherenceA one-directional coherence test: if navigator.maxTouchPoints is greater than zero, matchMedia("(any-pointer: coarse)") is expected to… - screen dimensions resolve via native prototype getters
screen-descriptorsFor width, height, availWidth, availHeight, colorDepth and pixelDepth this asks two questions: does the screen instance carry an own… - screen.orientation agrees with the screen's own dimensions
orientation-vs-screen-dimsscreen.orientation.type and screen.width/height are both device-space values sourced from the same display metrics, so they must agree: a… - visualViewport agrees with innerWidth/innerHeight
visual-viewport-vs-windowwindow.innerWidth and visualViewport.width are two independent readings of one viewport, and they are related by exactly one thing: the… - the CSS layout viewport width equals window.innerWidth
css-viewport-vs-innerwidth-coherencewindow.innerWidth and the width CSS media queries evaluate against are the same quantity read two ways. matchMedia("(min-width: Npx)") is… - navigation timing milestones run in their spec-defined causal order
nav-timing-orderAkamai Bot Manager v2 devotes an entire signal category to timing — navigation timing, resource timing, first paint, DOM-ready — and this…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Screen & display checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Screen & display — the family touch-createevent-coherence belongs to.