Whole Antidetect Catalog Donut Browser

Catalogue · Section 07

Network, TLS & HTTP fingerprint tooling

17 entries · 2ND ED., 1ST PRINTING

Corrected to 2026-08-14

12 ACTIVE · 1 SEMI · 1 NRND · 1 ARCHIVED · 2 DEAD

The layer below JavaScript: TLS ClientHello and HTTP/2 fingerprinting, impersonating clients that emit a browser-shaped handshake, and the passive tooling that reads them. This is the half of a fingerprint no page script can change, and it is where a browser-shaped page surface most often contradicts a tool-shaped connection.

The layer below JavaScript: TLS ClientHello and HTTP/2 fingerprinting, impersonating clients, and the passive tooling that reads them.


07 · Network, TLS & HTTP fingerprint tooling

17 entries
LicenceBSD-3-Clause
Pushed2026-08-02
Releasev1.8.2 · 2026-08-02
Stars2.5k
StateACTIVE
Silent12 d

uTLS

ACTIVE

Go TLS library that lets you choose your ClientHello. The foundation almost everything in this section stands on.

Source

Evidence

Why ACTIVE: pushed_at = 2026-08-02 — 12 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-08-02
archivedfalse
latest_releasev1.8.2 · 2026-08-02
license.spdx_idBSD-3-Clause
stargazers_count2500
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/refraction-networking/utls

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

LicenceMIT
Pushed2026-08-04
Release—
Stars74
StateACTIVE
Silent10 d

uQUIC

ACTIVE

The same idea for QUIC, which is where this problem is moving.

Source

Evidence

Why ACTIVE: pushed_at = 2026-08-04 — 10 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-08-04
archivedfalse
latest_release—
license.spdx_idMIT
stargazers_count74
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/refraction-networking/uquic

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

LicenceMIT
Pushed2026-08-08
Releasev2.1.0 · 2026-08-08
Stars2.7k
StateACTIVE
Silent6 d

curl-impersonate (lexiforest)

ACTIVE

The maintained fork: curl builds whose TLS and HTTP/2 handshakes match real browsers.

Source

Evidence

Why ACTIVE: pushed_at = 2026-08-08 — 6 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-08-08
archivedfalse
latest_releasev2.1.0 · 2026-08-08
license.spdx_idMIT
stargazers_count2700
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/lexiforest/curl-impersonate

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceMIT
Pushed2024-07-18
Release—
Stars6.8k
StateNRND
Silent757 d

curl-impersonate (lwthiker)

NRND[NRND]

The original. Two and a half times the stars of the maintained fork, and two years without a push.

Source

Evidence

Why NRND: pushed_at = 2024-07-18 — 757 days, inside the 365–1095 day NRND band.

FieldValue at this printing
pushed_at2024-07-18
archivedfalse
latest_release—
license.spdx_idMIT
stargazers_count6800
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/lwthiker/curl-impersonate

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

The most common single mistake in this whole field: installing the repository with the most stars. Check the push date first — that is all this catalogue is for. — ED.

See also · superseded by · alternatives

LicenceMIT
Pushed2026-08-08
Release—
Stars6.3k
StateACTIVE
Silent6 d

curl_cffi

ACTIVE

Python bindings over curl-impersonate; the usual practical entry point.

Source

Evidence

Why ACTIVE: pushed_at = 2026-08-08 — 6 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-08-08
archivedfalse
latest_release—
license.spdx_idMIT
stargazers_count6300
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/lexiforest/curl_cffi

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceBSD-4-Clause
Pushed2026-07-02
Releasev1.15.1 · 2026-07-02
Stars1.8k
StateACTIVE
Silent43 d

tls-client (Go)

ACTIVE

HTTP client with selectable TLS profiles, plus a shared-library build for other languages.

Source

Evidence

Why ACTIVE: pushed_at = 2026-07-02 — 43 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-07-02
archivedfalse
latest_releasev1.15.1 · 2026-07-02
license.spdx_idBSD-4-Clause
stargazers_count1800
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/bogdanfinn/tls-client

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceGPL-3.0
Pushed2026-07-07
Release—
Stars1.5k
StateACTIVE
Silent38 d

CycleTLS

ACTIVE

JA3-controllable HTTP client with Go and JavaScript interfaces.

Source

Evidence

Why ACTIVE: pushed_at = 2026-07-07 — 38 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-07-07
archivedfalse
latest_release—
license.spdx_idGPL-3.0
stargazers_count1500
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/Danny-Dasilva/CycleTLS

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceMIT
Pushed2026-04-17
Release—
Stars469
StateSEMI
Silent119 d

azuretls-client

SEMI

Go HTTP client with fine-grained control over the handshake and HTTP/2 settings frame.

Source

Evidence

Why SEMI: pushed_at = 2026-04-17 — 119 days, inside the 90–365 day SEMI band.

FieldValue at this printing
pushed_at2026-04-17
archivedfalse
latest_release—
license.spdx_idMIT
stargazers_count469
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/Noooste/azuretls-client

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceNOASSERTION
Pushed2026-07-21
Release—
Stars2k
StateACTIVE
Silent24 d

JA4+

ACTIVE

The current generation of network fingerprints: TLS, HTTP, TCP and more, each with its own suffix.

Source

Evidence

Why ACTIVE: pushed_at = 2026-07-21 — 24 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-07-21
archivedfalse
latest_release—
license.spdx_idNOASSERTION
stargazers_count2000
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/FoxIO-LLC/ja4

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

Licence is FoxIO's own, not an OSI identifier. GitHub reports NOASSERTION and so does this register — read the file before you vendor it. — ED.

See also · superseded by · alternatives

LicenceN/A
HTTP200
Checked2026-08-14
StateACTIVE
Silent—

JA4+ explainer

ACTIVE

The authors' own explanation of what each JA4 component encodes.

Source

Evidence

Why ACTIVE: No repository. The link check returned 200 at 2026-08-14T09:12:00Z, and 200–399 is ACTIVE for a non-repository entry.

FieldValue at this printing
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: HEAD https://blog.foxio.io/ja4%2B-network-fingerprinting

No repository, so there is no API field to re-read from a browser. A cross-origin liveness check has to be made server-side; this entry's status comes from the register's own sweep.

LicenceBSD-3-Clause
Pushed—
Release—
Stars3.1k
StateARCHIVED
Silent470 d

JA3 (Salesforce)

ARCHIVED[ARCHIVED]

The original TLS fingerprint. Archived by Salesforce; the format is still everywhere.

Listed as historical

Source

Evidence

Why ARCHIVED: archived = true, set 2025-05-01. A maintainer's own statement outranks every date rule.

FieldValue at this printing
pushed_at—
archivedtrue
archived_at2025-05-01
latest_release—
license.spdx_idBSD-3-Clause
stargazers_count3100
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/salesforce/ja3

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceN/A
HTTP200
Checked2026-08-14
StateACTIVE
Silent—

JA3 origin writeup

ACTIVE

The post that introduced JA3 and JA3S, kept for the reasoning rather than the code.

Source

Evidence

Why ACTIVE: No repository. The link check returned 200 at 2026-08-14T09:12:00Z, and 200–399 is ACTIVE for a non-repository entry.

FieldValue at this printing
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: HEAD https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967/

No repository, so there is no API field to re-read from a browser. A cross-origin liveness check has to be made server-side; this entry's status comes from the register's own sweep.

LicenceGPL-3.0
Pushed2026-07-27
Release—
Stars445
StateACTIVE
Silent18 d

TrackMe (tls.peet.ws)

ACTIVE

The server behind tls.peet.ws — self-host it and you have your own handshake mirror.

Source

Evidence

Why ACTIVE: pushed_at = 2026-07-27 — 18 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-07-27
archivedfalse
latest_release—
license.spdx_idGPL-3.0
stargazers_count445
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/pagpeter/TrackMe

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

LicenceApache-2.0
Pushed2026-08-13
Release—
Stars1.1k
StateACTIVE
Silent1 d

rama

ACTIVE

Rust framework for building proxies with explicit control over the emitted fingerprint.

Source

Evidence

Why ACTIVE: pushed_at = 2026-08-13 — 1 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-08-13
archivedfalse
latest_release—
license.spdx_idApache-2.0
stargazers_count1100
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/plabayo/rama

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceNO LICENCE DECLARED
Pushed2021-08-14
Release—
Stars40
StateDEAD
Silent1826 d

nginx-http2-fingerprint

DEAD[DEAD]

Reference implementation of HTTP/2 fingerprinting inside nginx. Read it; do not deploy it.

No licence declared · Listed as historical

Source

Evidence

Why DEAD: pushed_at = 2021-08-14 — 1826 days, past the 1095-day outer threshold.

FieldValue at this printing
pushed_at2021-08-14
archivedfalse
latest_release—
license.spdx_idnull (none declared)
stargazers_count40
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/Xetera/nginx-http2-fingerprint

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

LicenceMIT
Pushed2026-08-13
Release—
Stars44.7k
StateACTIVE
Silent1 d

mitmproxy

ACTIVE

The general-purpose interception proxy. Not anti-detect tooling, and the fastest way to see what your stack actually sends.

Source

Evidence

Why ACTIVE: pushed_at = 2026-08-13 — 1 days, within the 90-day ACTIVE threshold.

FieldValue at this printing
pushed_at2026-08-13
archivedfalse
latest_release—
license.spdx_idMIT
stargazers_count44700
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/mitmproxy/mitmproxy

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives

LicenceNO LICENCE DECLARED
Pushed2019-07-09
Release—
Stars521
StateDEAD
Silent2593 d

p0f

DEAD[DEAD]

Classic passive OS fingerprinting from TCP/IP behaviour. The technique predates all of this and still works.

No licence declared · Listed as historical

Source

Evidence

Why DEAD: pushed_at = 2019-07-09 — 2593 days, past the 1095-day outer threshold.

FieldValue at this printing
pushed_at2019-07-09
archivedfalse
latest_release—
license.spdx_idnull (none declared)
stargazers_count521
http_status200
fetched_at2026-08-14T09:12:00Z
rubric_edition2nd, in force

Endpoint: GET https://api.github.com/repos/p0f/p0f

unauthenticated · 60 req/hr

A live read does not change what is printed above it. The site records that you ran it; what GitHub returned is not kept. The printed state moves only when the register is swept and a new printing is issued. raw JSON

See also · superseded by · alternatives


Why the handshake identifies you before a single byte of application data

A TLS ClientHello carries an ordered list of cipher suites, extensions, curves and signature algorithms, and that ordering is a property of the library that composed it rather than of the protocol. Two different TLS stacks negotiating the same connection produce different orderings, and hashing that ordering produces a fingerprint that identifies the client software before any request has been sent.

HTTP/2 adds a second layer of the same kind: the settings frame values, the window size, the priority information and the pseudo-header ordering all differ by implementation. Both were described publicly by the detection side, and both are collected cheaply at the edge, which is why they are among the first things a serious defence looks at.

Impersonation, and the version problem nobody mentions

The tooling here works by emitting a handshake that matches a specific browser build rather than the one the client library would compose naturally. That is a genuine solution and it introduces a genuine new problem: a handshake matching a browser version that no longer exists in the wild is its own kind of signal, and the preset lists in these projects age exactly as fast as browsers ship.

So the field to read on every entry in this section is not only the push date but which impersonation targets the current build carries. A recently pushed library with a two-year-old preset list is presenting a browser that nobody runs.


State marks used in this section


Questions about tls and http fingerprint tooling

Answered from the fields printed above, and from nothing this register has not checked.

What is a JA3 or JA4 fingerprint?

A hash, or in the newer format a structured string, computed from the ordered contents of a TLS ClientHello — cipher suites, extensions, curves and so on. It identifies the client library rather than the user, and it is collected passively at the edge before any application data is exchanged. The newer format is readable by component, which is what makes it debuggable rather than merely comparable.

Can JavaScript change my TLS fingerprint?

No. The handshake is composed by the network stack before any page code exists, which is why a stealth plugin cannot touch it and why a browser-shaped page surface over a Python-shaped handshake is a contradiction that no amount of navigator patching resolves.

Do I need an impersonating HTTP client if I am driving a real browser?

Generally not for the browser's own requests, which already emit a real browser handshake. You do need one for anything you fetch outside the browser, and mixing the two — a real browser for pages and a default HTTP client for the API calls beside them — is a common and avoidable inconsistency.


Donut Browser is filed in section 01 of this same catalogue, under the same rubric, with the same fields printed against it and no exemption: an open-source anti-detect browser under AGPL-3.0 whose Wayfern Chromium fork applies fingerprint overrides at engine level over CDP rather than by patching page JavaScript, with a local REST API and MCP server on your own machine, self-hostable sync, zero telemetry, and a pre-launch gate that refuses to start a profile when the proxy's exit geography contradicts the profile's fingerprint. It is judged here the same way everything in this section is judged.

Download Donut Browser

curl -fsSL https://donutbrowser.com/install.sh | sh

macOS · Windows · Linux · Nix. Desktop only. Source, AGPL-3.0 · Its entry · The rubric · The data, CC0 · The keepers' disclosure

Other sections