# Roadmap

> What we plan to build next, why, and what WhiskerJS will not do. Every item rests on public sources listed at the bottom of the page.

Source: https://whiskerjs.com/roadmap/ (last updated 2026-10-26)

> **In plain words:**
>
> WhiskerJS today reads 47 browser and device signals and returns them as one JSON result, without sending or storing anything. The first steps, all about **reliability**, are done: telling apart real values from values a privacy browser has deliberately changed, keeping ids linkable when the library updates, spotting automation through values that do not fit together, and testing in real browsers. What follows builds on them. New signals are added **outside the id first** and join it only after measurement shows they are stable. The rules stay the same: no network, no storage, no permission prompts, no console output, no verdicts.

**Priority**: P1 means we do it in that phase, P2 when the P1 items are done, P3 only with a clear use. **Effort**: S is up to two days, M up to two weeks, L more. Plans can change as measurements come in.

## Done so far

These items from the first “Now” list are built and in the library on its main branch (the [live demo](https://whiskerjs.com/demo/) runs them). [What’s new](https://whiskerjs.com/whats-new/) has the details of each version.

| Item | Status |
| --- | --- |
| **Spot “seeded” noise.** Known-answer probes for canvas, WebGL and audio | Done in signalsVersion 6: the [`noise_profile`](https://whiskerjs.com/signals/noise-profile/) component and the `seeded_noise` reason |
| **Recognise more privacy modes.** Firefox Fingerprinting Protection, Safari Advanced Fingerprinting Protection, Tor and Mullvad, Android WebView; Brave’s newer WebGL and WebGPU protections | Done in signalsVersion 6: ten browser classes; see [the exclusion table](https://whiskerjs.com/docs/how-it-works/#the-exclusion-table) |
| **Read capped values more than once.** CPU core count and memory read 16 times; Chrome’s new memory buckets tagged | Done in signalsVersion 7: the `read_varies` reason, Safari’s `4_8` bucket and the `;c146` tag |
| **Keep ids across upgrades.** The id computed the old way, for one release after a change | Done with signalsVersion 7: [previous ids](https://whiskerjs.com/docs/identifiers/#previous-ids-linking-across-a-version-bump) |
| **First consistency checks.** CSS screen size, Intl against Date, User-Agent against Client Hints, Playwright’s exposed functions, virtual machine graphics | Done in signalsVersion 8: five new [integrity flags](https://whiskerjs.com/docs/integrity/) (19 in total) |
| **Real browsers in CI.** Chromium, Firefox (also with its privacy settings), WebKit and branded Chrome | Done in signalsVersion 9, which fixed what it found (canvas now reads pixels; a WebKit false positive); per-browser golden snapshots not yet added |
| **Published test protocol first.** How uniqueness and stability will be measured, written down before any data | Protocol written; no data collected yet, so no figures are published |

## Now: the next 2 to 4 weeks

| Item | Priority | Effort | Why, in plain words |
| --- | --- | --- | --- |
| **Time and version every signal.** Each signal reports how long it took and which revision of its collector ran | P1 | S | Servers can then tell which signals changed and why, and how much each one costs |
| **Cheap new signals, outside the id.** Pointer and hover media queries, colour scheme, WebGL2 limits, all WebGPU limits and shader language features, full text and emoji measurements | P1 | M | Each is quick to read and needs no prompt or network; they join the id only once measured as stable |
| **Size and speed budgets.** Measure and publish the bundle size; let the page breathe between collectors | P1 | S | Sites choose libraries by cost; long tasks make pages feel slow |
| **Ready for a public repository.** Security policy, automated security checks, licence headers | P1 | S | Needed before the first release and outside contributions |
| **Decide on diagnostics.** An open proposal would send small, sampled diagnostic reports by default, which would change the no-network promise. It waits on the maintainer’s decision | P1 | S | The privacy promise on this site depends on it |

## Next: 1 to 3 months

| Item | Priority | Effort | Why, in plain words |
| --- | --- | --- | --- |
| **Engine version vector.** Which JavaScript, WebAssembly and Intl features exist, and which device APIs are present (presence only) | P1 | M | Adds little to the id but shows when a browser claims to be a version it cannot be |
| **Version mismatch flag.** Fires when a browser claims to be older than a feature it has | P1 | S | Anti-detect browsers often claim another engine or version |
| **More consistency checks.** Graphics names against the platform and WebGPU, two media APIs against each other, impossible window sizes, a phone with no touch, fonts from another operating system | P1 | M | Spoofing tools tend to change one API at a time |
| **Video decoding capabilities.** Whether common codecs decode efficiently, read without any DRM query | P2 | S | Shows hardware video decoders, a real device trait |
| **More rendering signals, reported.** System colours, font smoothing, SVG text sizes, a small GPU maths drawing, screen orientation | P2 | M | Different engine paths give different, mostly stable, results |
| **Compare two canvas types.** Draw the same scene on a normal and an offscreen canvas | P2 | S | Extensions often patch only one of them |
| **Optional worker check.** Only if the site provides a worker file of its own: read key values again inside it and compare | P2 | M | A worker is harder for extensions to fake; the site makes the request, so WhiskerJS still makes none |
| **Version-free variants.** Browser and driver versions also reported without minor numbers | P2 | S | Lets servers compare devices across automatic updates |
| **Optional server package.** A separate open-source package: group-by-group matching that treats very common setups as a crowd rather than one device, header checks, the JA4 TLS fingerprint, and open IP lists | P1 | L | Matching quality is decided on the server; checks across network and browser layers catch scripts that pretend to be browsers |
| **Real devices, including iPhones.** Nightly runs on a device farm and real Safari | P2 | M | Every iPhone browser outside the EU uses WebKit, and test WebKit is not Safari |
| **Packaging.** Import only the collectors you need; a single script file for script tags; checked types | P2 | M | Smaller pages for sites that need fewer signals |
| **First package release (0.x).** Once the repository is public, published with provenance from CI | P1 | S | Lets anyone verify that the package was built from this source |
| **A page per signal with measured figures.** What each signal reads, how stable and distinctive it measured, and what it costs | P2 | M | Makes the trade-offs open to inspection |

## Later

| Item | Priority | Effort | Why, in plain words |
| --- | --- | --- | --- |
| Learned signal weights in the server package | P2 | M | Weight signals by how stable and distinctive they measured, once there is data |
| Faster matching for large sites | P2 | M | Published linking methods slowed down and lost accuracy at scale |
| Replay test against the anti-replay binding | P2 | M | Research showed that copied browser values can fool matchers |
| A public, opt-in test page | P3 | L | Only with explicit consent, digests only, no IP addresses kept and an ethics review |
| HTTP/2 and later network-level checks in the server package | P2 to P3 | M to L | Separate real browsers from HTTP libraries |
| Small extra signals (CSS support list, passkey capabilities, Global Privacy Control and others) | P3 | S each | Little new information each; useful for consistency |
| GPU timing research module, opt-in and off by default | P3 | L | Can tell identical hardware apart, but costs seconds of GPU work |
| Framework wrappers (React first) | P3 | M | Easier adoption once the core settles |
| External security audit before 1.0 | P2 | M | An outside view of tampering and replay risks |

## Not doing

| What | Why not |
| --- | --- |
| WebRTC, media device lists, network information, battery, geolocation | They can trigger network activity, prompts or permission-linked data |
| Storage quota | Browsers now report it in a way that tells little, and it changes with use |
| DRM key system queries, payment checks, installed related apps | They can show browser UI, fetch files or reveal installed apps |
| Starting sensors, screen details or any device chooser | They prompt the user; only “does this API exist” is read |
| Gamepad values | Empty until the user presses a button, by design |
| Detecting DevTools through the console | Needs console output, and stopped working in 2025 |
| Workers the library builds itself | A page’s security policy can block them and report the block over the network |
| Timing tricks inside the id | Too unstable from run to run |
| Detecting installed extensions | Too invasive for a device collector |
| Mouse and keyboard behaviour in the core | Outside a device collector |
| Parsing the User-Agent in the browser | Belongs on the server |
| JA3 | Chrome shuffles the data it is computed from, so it changes per connection |
| The JA4+ family beyond JA4 | Its licence allows non-commercial use only |
| Scores, verdicts or stored ids in the browser | WhiskerJS collects; the site’s server decides |

## Sources

All sources were read on 2026-10-26. Some were available only as an abstract or a summary; the full roadmap in the library repository (`docs/ROADMAP.md`) marks which.

### Specifications and vendor documentation

- [W3C, Mitigating Browser Fingerprinting in Web Specifications (Group Note, 2025-09-25)](https://www.w3.org/TR/fingerprinting-guidance/)
- [W3C TAG, Unsanctioned Web Tracking (2015-07-17)](https://www.w3.org/2001/tag/doc/unsanctioned-tracking/)
- [W3C WebGPU, privacy considerations](https://www.w3.org/TR/webgpu/)
- [MDN, WGSLLanguageFeatures](https://developer.mozilla.org/en-US/docs/Web/API/WGSLLanguageFeatures)
- [MDN, GPU.getPreferredCanvasFormat](https://developer.mozilla.org/en-US/docs/Web/API/GPU/getPreferredCanvasFormat)
- [MDN, GPUAdapter.limits](https://developer.mozilla.org/en-US/docs/Web/API/GPUAdapter/limits)
- [MDN, GPUAdapter.info](https://developer.mozilla.org/en-US/docs/Web/API/GPUAdapter/info)
- [Chrome, New in WebGPU 120](https://developer.chrome.com/blog/new-in-webgpu-120)
- [web.dev, WebGPU supported in major browsers](https://web.dev/blog/webgpu-supported-major-browsers)
- [W3C CSS Color 4, system colours](https://www.w3.org/TR/css-color-4/)
- [MDN, TextMetrics](https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics)
- [MDN, prefers-reduced-transparency](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-transparency)
- [MDN, video-dynamic-range](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/video-dynamic-range)
- [MDN, scripting media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/scripting)
- [MDN, inverted-colors](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/inverted-colors)
- [MDN, Screen.isExtended](https://developer.mozilla.org/en-US/docs/Web/API/Screen/isExtended)
- [W3C Media Capabilities (Working Draft, 2026-10-18)](https://www.w3.org/TR/media-capabilities/)
- [MDN, MediaCapabilities.decodingInfo](https://developer.mozilla.org/en-US/docs/Web/API/MediaCapabilities/decodingInfo)
- [MDN, Storage quotas and eviction criteria](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria)
- [blink-dev, PSA on a predictable reported storage quota](https://groups.google.com/a/chromium.org/g/blink-dev/c/7q0YGQNVkjs/m/mpYkQVWpAQAJ)
- [MDN, Performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)
- [MDN, crossOriginIsolated](https://developer.mozilla.org/en-US/docs/Web/API/Window/crossOriginIsolated)
- [MDN, Intl.supportedValuesOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf)
- [Mozilla bug 2044813, canonical time zones under FPP](https://bugzilla.mozilla.org/show_bug.cgi?id=2044813)
- [MDN, Temporal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal)
- [web.dev, New to the web platform in May 2025](https://web.dev/blog/web-platform-05-2025)
- [MDN, Error.prototype.stack](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack)
- [GoogleChromeLabs, wasm-feature-detect](https://github.com/GoogleChromeLabs/wasm-feature-detect)
- [W3C Generic Sensor API](https://www.w3.org/TR/generic-sensor/)
- [MDN, DeviceOrientationEvent.requestPermission](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/requestPermission_static)
- [WebKit, Tracking Prevention](https://webkit.org/tracking-prevention/)
- [W3C Gamepad](https://www.w3.org/TR/gamepad/)
- [W3C Compute Pressure](https://www.w3.org/TR/compute-pressure/)
- [W3C Device Posture](https://www.w3.org/TR/device-posture/)
- [MDN, PublicKeyCredential.getClientCapabilities](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/getClientCapabilities_static)
- [W3C Payment Request](https://www.w3.org/TR/payment-request/)
- [MDN, Navigator.getInstalledRelatedApps](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getInstalledRelatedApps)
- [Web Speech API](https://webaudio.github.io/web-speech-api/)
- [Global Privacy Control](https://w3c.github.io/gpc/)
- [MDN, Document.featurePolicy](https://developer.mozilla.org/en-US/docs/Web/API/Document/featurePolicy)
- [MDN, Navigator.userActivation](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userActivation)
- [Mozilla bug 1320796, service workers in private browsing](https://bugzilla.mozilla.org/show_bug.cgi?id=1320796)
- [MDN, CSP worker-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/worker-src)
- [MDN, Worker constructor](https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker)
- [MDN, NavigatorUAData.getHighEntropyValues](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues)
- [Chrome, Headless mode](https://developer.chrome.com/docs/chromium/headless)

### Browser privacy changes

- [Privacy Sandbox feature status (updated 2026-08-14)](https://privacysandbox.google.com/overview/status)
- [Update on plans for Privacy Sandbox technologies (2025-10-17)](https://privacysandbox.google.com/blog/update-on-plans-for-privacy-sandbox-technologies)
- [GoogleChrome/ip-protection (archived 2025-11-03)](https://github.com/GoogleChrome/ip-protection)
- [Incognito Script Blocking explainer](https://github.com/explainers-by-googlers/script-blocking)
- [Chromium, User-Agent Reduction](https://www.chromium.org/updates/ua-reduction/)
- [blink-dev, Intent to Ship: Device Memory limits (2026-01-20)](https://groups.google.com/a/chromium.org/g/blink-dev/c/vXtAmrVZeDk/m/kO39WH6NAwAJ)
- [Android Developers, UA reduction on Android WebView (2024-12-06)](https://android-developers.googleblog.com/2024/12/user-agent-reduction-on-android-webview.html)
- [WebKit, Safari Technology Preview 254 (2026-10-08)](https://webkit.org/blog/18420/release-notes-for-safari-technology-preview-254/)
- [WebKit, Features for Safari 27.0 (2026-09-17)](https://webkit.org/blog/18325/webkit-features-for-safari-27-0/)
- [WebKit, Features in Safari 26.0 (2025-09-15)](https://webkit.org/blog/17333/webkit-features-in-safari-26-0/)
- [WebKit, News from WWDC25 (2025-06-09)](https://webkit.org/blog/16993/news-from-wwdc25-web-technology-coming-this-fall-in-safari-26-beta/)
- [WebKit, Private Browsing 2.0 (2024-07-16)](https://webkit.org/blog/15697/private-browsing-2-0/)
- [WebKit, Features in Safari 17.0 (2023-09-18)](https://webkit.org/blog/14445/webkit-features-in-safari-17-0/)
- [Apple, Safari User Guide: advanced fingerprinting protection](https://support.apple.com/en-gb/guide/safari/ibrw1069/mac)
- [Apple, Alternative browser engines in the EU](https://developer.apple.com/support/alternative-browser-engines/)
- [Mozilla, Firefox fingerprinting protections (2025-11-10)](https://blog.mozilla.org/en/firefox/fingerprinting-protections/)
- [Firefox 151 release notes (2026-05-19)](https://www.firefox.com/en-US/firefox/151.0/releasenotes/)
- [Mozilla wiki, Fingerprinting (2026-05-12)](https://wiki.mozilla.org/Fingerprinting)
- [mozilla-central, RFPTargetsDefault.inc](https://searchfox.org/mozilla-central/source/toolkit/components/resistfingerprinting/RFPTargetsDefault.inc)
- [mozilla-central, RFPTargets.inc](https://searchfox.org/mozilla-central/source/toolkit/components/resistfingerprinting/RFPTargets.inc)
- [Firefox source, nsRFPService.h](https://raw.githubusercontent.com/mozilla-firefox/firefox/main/toolkit/components/resistfingerprinting/nsRFPService.h)
- [Mozilla bug 1816189, RFP canvas noise](https://bugzilla.mozilla.org/show_bug.cgi?id=1816189)
- [Mozilla bug 1360039, RFP hardwareConcurrency](https://bugzilla.mozilla.org/show_bug.cgi?id=1360039)
- [Brave, WebGL and WebGPU fingerprinting protections (2026-08-13)](https://brave.com/privacy-updates/38-webgl-webgpu-fingerprinting-protections/)
- [Brave, Sunsetting strict fingerprinting mode (2024-01-18)](https://brave.com/privacy-updates/28-sunsetting-strict-fingerprinting-mode/)
- [Brave, Language fingerprinting protections (2022)](https://brave.com/privacy-updates/17-language-fingerprinting/)
- [Brave, Fingerprinting defenses 2.0](https://brave.com/privacy-updates/4-fingerprinting-defenses-2.0/)
- [Brave wiki, Fingerprinting Protections](https://github.com/brave/brave-browser/wiki/Fingerprinting-Protections)
- [Brave, farbling test page](https://dev-pages.brave.software/fingerprinting/farbling.html)
- [Tor Project, Tor Browser 15.0 (2025-10-28)](https://blog.torproject.org/new-release-tor-browser-150/)
- [Tor Project, Tor Browser 15.0.26 (2026-10-21)](https://blog.torproject.org/new-release-tor-browser-15026/)
- [Mullvad Browser, hard facts (2026-01-13)](https://mullvad.net/en/browser/hard-facts)
- [Microsoft, Edge tracking prevention (2026-09-02)](https://learn.microsoft.com/en-us/microsoft-edge/web-platform/tracking-prevention)
- [DuckDuckGo, web tracking protections](https://duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/)
- [DuckDuckGo, content-scope-scripts features](https://github.com/duckduckgo/content-scope-scripts/tree/main/injected/src/features)
- [ICO, response to Google’s fingerprinting policy change (2024-12-19)](https://ico.org.uk/about-the-ico/media-centre/news-and-blogs/2024/12/our-response-to-google-s-policy-change-on-fingerprinting/)
- [ICO, storage and access technologies: exemptions](https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guidance-on-the-use-of-storage-and-access-technologies/what-are-the-exceptions/)
- [Google, platforms program policy update (effective 2025-02-16)](https://support.google.com/platformspolicy/answer/15610408?hl=en)
- [EDPB, Guidelines 2/2023 on Article 5(3) ePrivacy, version 2 (2024-10-07)](https://www.edpb.europa.eu/system/files/documents/2024-10/edpb_guidelines_202302_technical_scope_art_53_eprivacydirective_v2_en_0.pdf)
- [EDPB, Guidelines 1/2024 on legitimate interest (2024-10-08)](https://www.edpb.europa.eu/system/files/2024-10/edpb_guidelines_202401_legitimateinterest_en.pdf)

### Academic papers

- [Laperdrix, Bielova, Baudry, Avoine, Browser Fingerprinting: A Survey (ACM TWEB 2020), with the comparison tables for Panopticlick, AmIUnique and Hiding in the Crowd](https://ar5iv.labs.arxiv.org/html/1905.01051)
- [Andriamilanto, Allard, Le Guelvouit, Garel, A Large-scale Empirical Analysis of Browser Fingerprints Properties for Web Authentication (ACM TWEB 2022)](https://ar5iv.labs.arxiv.org/html/2006.09511)
- [Andriamilanto, Allard, Le Guelvouit, FPSelect (ACSAC 2020)](https://ar5iv.labs.arxiv.org/html/2010.06404)
- [Vastel, Laperdrix, Rudametkin, Rouvoy, FP-STALKER (IEEE S&P 2018)](https://ieeexplore.ieee.org/document/8418634)
- [Pugliese, Riess, Gassmann, Benenson, Long-Term Observation on Browser Fingerprinting (PoPETs 2020)](https://petsymposium.org/popets/2020/popets-2020-0041.php)
- [FAU, browser fingerprinting research group](https://www.cs1.tf.fau.de/research/human-factors-in-security-and-privacy-group/browser-fingerprinting/)
- [Eckersley, How Unique Is Your Web Browser? (PETS 2010)](https://www.springerprofessional.de/en/how-unique-is-your-web-browser/3331922)
- [Laperdrix, Rudametkin, Baudry, Beauty and the Beast (IEEE S&P 2016)](https://hal.archives-ouvertes.fr/hal-01285470)
- [Li, Cao, Who Touched My Browser Fingerprint? (IMC 2020)](https://yinzhicao.org/fpmeasurement/imc20.pdf)
- [Liu, Shrestha, Saxena, Gummy Browsers (2021)](https://arxiv.org/abs/2110.10129)
- [Samlioglu, threshold-based linking scheme for browser fingerprints (Sabanci University thesis, 2025)](https://research.sabanciuniv.edu/id/eprint/53631/)
- [Bacis et al., Assessing Web Fingerprinting Risk (WWW 2024)](https://arxiv.org/html/2403.15607)
- [How Unique is Whose Web Browser? The role of demographics in browser fingerprinting among US users (2024)](https://arxiv.org/html/2410.06954)
- [University of Cambridge, SensorID](https://www.cst.cam.ac.uk/node/10022)
- [Kurtz et al., Fingerprinting Mobile Devices Using Personalized Configurations (PoPETs 2016)](https://petsymposium.org/popets/2016/popets-2015-0027.php)
- [Laor et al., DrawnApart (NDSS 2022)](https://arxiv.org/abs/2201.09956)
- [AmIUnique blog, explainer on DrawnApart](https://blog.amiunique.org/an-explicative-article-on-drawnapart-a-gpu-fingerprinting-technique/)
- [Hohentanner et al., AtomicIncrement (WiSec 2025)](https://cris.fau.de/publications/348779971)
- [Laor, Oren, LockedApart (poster)](https://ojs.ub.rub.de/index.php/uASC/article/view/12008)
- [Trampert et al., Cascading Spy Sheets (NDSS 2025)](https://www.ndss-symposium.org/ndss-paper/cascading-spy-sheets/)
- [Fifield, Egelman, Fingerprinting web users through font metrics (FC 2015)](https://blues.cs.berkeley.edu/?p=152)
- [Venugopalan et al., FP-Inconsistent (2024)](https://arxiv.org/abs/2406.07647)
- [Vastel et al., FP-Scanner (USENIX Security 2018)](https://www.usenix.net/system/files/conference/usenixsecurity18/sec18-vastel.pdf)
- [Web Runner 2049 (DIMVA 2020)](https://hal.archives-ouvertes.fr/hal-02612454)
- [Li et al., Good Bot, Bad Bot (IEEE S&P 2021)](https://www.securitee.org/files/goodbotbadbot_oakland2021.pdf)
- [Laperdrix et al., Fingerprinting in Style (USENIX Security 2021)](https://par.nsf.gov/servlets/purl/10301513)
- [Schwarz et al., JavaScript Template Attacks (NDSS 2019)](https://ndss-symposium.org/ndss-paper/javascript-template-attacks-automatically-inferring-host-information-for-targeted-exploits)
- [Patat et al., Widevine client id leakage (PoPETs 2023)](https://arxiv.org/abs/2308.05416)
- [LWN, getClientRects fingerprinting in Tor Browser (2016)](https://lwn.net/Articles/679147/)
- [Mozilla bug 2020894, emoji measureText against DOM widths](https://bugzilla.mozilla.org/show_bug.cgi?id=2020894)
- [Tor bugs list, WebGL readPixels entropy (2019)](https://lists.torproject.org/pipermail/tor-bugs/2019-May/188627.html)

### Automation and anti-detect tools (public documentation)

- [Castle blog, detecting Playwright (2025-03-19)](https://blog.castle.io/how-to-detect-headless-chrome-bots-instrumented-with-playwright/)
- [Castle blog, detecting Puppeteer (2025-03-13)](https://blog.castle.io/how-to-detect-headless-chrome-bots-instrumented-with-puppeteer-2/)
- [Castle blog, why a classic CDP signal stopped working (2025-08-28)](https://blog.castle.io/why-a-classic-cdp-bot-detection-signal-suddenly-stopped-working-and-nobody-noticed/)
- [rebrowser-patches](https://github.com/rebrowser/rebrowser-patches)
- [Patchright](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright)
- [puppeteer-extra-plugin-stealth evasions](https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth/evasions)
- [undetected-chromedriver](https://github.com/ultrafunkamsterdam/undetected-chromedriver)
- [nodriver](https://github.com/ultrafunkamsterdam/nodriver)
- [Selenium-Driverless](https://github.com/kaliiiiiiiiii/Selenium-Driverless)
- [Camoufox, fingerprint injection](https://camoufox.com/fingerprint/)
- [Multilogin, fingerprint settings help](https://multiloginx.helpjuice.com/en_US/browser-profile-setup/profile-settings-fingerprint-section)
- [Kameleo, product page](https://kameleo.io/)
- [web3dsurvey, WebGL vendor strings (Android emulator)](https://web3dsurvey.com/webgl/vendors/Google%20%28Google%20Inc.%20%28Google%29%29)

### Server-side signals and open data

- [FoxIO, JA4 repository and licences](https://github.com/FoxIO-LLC/ja4)
- [FoxIO, JA4 technical details](https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md)
- [Cloudflare, JA3 and JA4 fingerprints](https://developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint/)
- [Cloudflare, cf.bot_management.ja4 field](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.bot_management.ja4/)
- [Cloudflare Workers, Request and its `cf` properties](https://developers.cloudflare.com/workers/runtime-apis/request/)
- [Go, crypto/tls ClientHelloInfo](https://pkg.go.dev/crypto/tls#ClientHelloInfo)
- [Fastly, a first look at Chrome’s TLS ClientHello permutation](https://fastly.com/blog/a-first-look-at-chromes-tls-clienthello-permutation-in-the-wild)
- [Shuster, Segal, Passive Fingerprinting of HTTP/2 Clients (Black Hat EU 2017)](https://www.blackhat.com/docs/eu-17/materials/eu-17-Shuster-Passive-Fingerprinting-Of-HTTP2-Clients.pdf)
- [Cloudflare blog, JA4 signals](https://blog.cloudflare.com/ja4-signals/)
- [p0f v3](https://lcamtuf.coredump.cx/p0f)
- [Tor Project, bulk exit list](https://check.torproject.org/torbulkexitlist)
- [AWS, IP address ranges](https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html)
- [iptoasn.com](https://iptoasn.com/)
- [Spamhaus, DROP lists and terms](https://www.spamhaus.org/blocklists/do-not-route-or-peer/)
- [FireHOL blocklist-ipsets](https://github.com/firehol/blocklist-ipsets)
- [Apple, Prepare your network for iCloud Private Relay](https://developer.apple.com/support/prepare-your-network-for-icloud-private-relay/)

### Engineering, release and governance

- [bundlejs, FingerprintJS 5.3.0 size](https://deno.bundlejs.com/?q=@fingerprintjs/fingerprintjs)
- [bundlejs, ThumbmarkJS 1.12.0 size](https://deno.bundlejs.com/?q=@thumbmarkjs/thumbmarkjs)
- [bundlejs, BotD 2.0.0 size](https://deno.bundlejs.com/?q=@fingerprintjs/botd)
- [FingerprintJS repository](https://github.com/fingerprintjs/fingerprintjs)
- [FingerprintJS, version policy](https://raw.githubusercontent.com/fingerprintjs/fingerprintjs/master/docs/version_policy.md)
- [FingerprintJS, API docs](https://raw.githubusercontent.com/fingerprintjs/fingerprintjs/master/docs/api.md)
- [ThumbmarkJS repository](https://github.com/thumbmarkjs/thumbmarkjs)
- [size-limit](https://github.com/ai/size-limit)
- [webpack, tree shaking](https://webpack.js.org/guides/tree-shaking/)
- [esbuild, API](https://esbuild.github.io/api/#metafile)
- [web.dev, Optimize long tasks](https://web.dev/articles/optimize-long-tasks)
- [MDN, Scheduler.yield](https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/yield)
- [MDN, Long animation frame timing](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Long_animation_frame_timing)
- [MDN, OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas)
- [Next.js, lazy loading](https://nextjs.org/docs/app/guides/lazy-loading)
- [Are the types wrong](https://github.com/arethetypeswrong/arethetypeswrong.github.io)
- [Changesets](https://github.com/changesets/changesets)
- [Playwright, browsers](https://playwright.dev/docs/browsers)
- [Vitest, browser mode](https://vitest.dev/guide/browser/)
- [WebKit, WebDriver support in Safari](https://webkit.org/blog/6900/webdriver-support-in-safari-10/)
- [BrowserStack, open source program](https://www.browserstack.com/open-source)
- [Sauce Labs, Open Sauce announcement](https://saucelabs.com/resources/blog/announcing-open-sauce-free-unlimited-testing-for-open-source-projects)
- [AWS Device Farm pricing](https://aws.amazon.com/device-farm/pricing)
- [Center for Open Science, preregistration](https://www.cos.io/initiatives/prereg)
- [AmIUnique, FAQ](https://amiunique.org/faq)
- [npm, trusted publishers](https://docs.npmjs.com/trusted-publishers)
- [GitHub changelog, npm trusted publishing generally available (2025-07-31)](https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/)
- [GitHub changelog, npm token changes (2025-11-05)](https://github.blog/changelog/2025-11-05-npm-security-update-classic-token-creation-disabled-and-granular-token-changes/)
- [GitHub changelog, classic tokens revoked (2025-12-09)](https://github.blog/changelog/2025-12-09-npm-classic-tokens-revoked-session-based-auth-and-cli-token-management-now-available/)
- [npm, generating provenance statements](https://docs.npmjs.com/generating-provenance-statements)
- [SLSA, security levels](https://slsa.dev/spec/v1.0/levels)
- [OpenSSF Scorecard](https://github.com/ossf/scorecard)
- [OpenSSF Best Practices, passing criteria](https://www.bestpractices.dev/en/criteria/0)
- [GitHub, private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/working-with-repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository)
- [Developer Certificate of Origin](https://developercertificate.org/)
- [Apache, applying the Apache License](https://www.apache.org/legal/apply-license.html)
- [Apache, licensing how-to](https://infra.apache.org/licensing-howto.html)
- [REUSE specification](https://reuse.software/spec/)
