
Product
Socket MCP Adds Org Alerts, Threat Feed Review, and Package Inspection
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.
tls-client-node
Advanced tools
Node.js client for bogdanfinn/tls-client with native shared-library loading and optional managed runtime support.
Native-first Node.js wrapper for browser-like TLS profiles.
Explicit lifecycle, upstream-aligned payloads, and published package distribution without singleton-style API state.
Browser-like TLS profiles are not just about the user-agent header. Servers inspect the full handshake,
HTTP/2 behavior, and related transport traits. tls-client-node gives Node.js a cleaner wrapper around that
upstream capability while keeping the lifecycle explicit instead of hiding it behind singleton state.
tls-client-node is a source-available Node.js client for bogdanfinn/tls-client. It uses direct shared-library loading on supported local platforms by default, keeps lifecycle control explicit through TLSClient and Session, and can also run through tls-client-api when that mode is explicitly selected.
| Focus | What you get |
|---|---|
| Native-first local runtime | Uses the upstream shared library directly on supported platforms instead of forcing a local sidecar process by default. |
| Explicit lifecycle | TLSClient and Session keep ownership obvious, instead of hiding everything behind global init and destroy calls. |
| Upstream alignment | Custom TLS payloads and profile identifiers are kept close to Bogdan Finn's tls-client contract. |
| Migration practicality | Common node-tls-client aliases such as ja3string, timeout, hostOverride, and randomTlsExtensionOrder are supported. |
| Modern package surface | Published npm package with strict TypeScript types, named ESM imports, and CommonJS require support. |
require support..dll, .dylib, or .so.runtimeMode: "managed".npm install tls-client-node
# or
yarn add tls-client-node
# or
pnpm add tls-client-node
During postinstall, the package tries to download the matching upstream shared library for the current platform. If that step is skipped or fails, the required local asset is downloaded lazily on first startup.
Environment variables:
TLS_CLIENT_SKIP_DOWNLOAD=1 disables install-time downloads.TLS_CLIENT_VERSION=1.14.0 pins the upstream asset version.TLS_CLIENT_API_VERSION=1.14.0 is also recognized as an alias for TLS_CLIENT_VERSION.ESM named imports work directly:
import {
ClientIdentifier,
TLSClient,
} from "tls-client-node";
const client = new TLSClient();
const session = client.session({
clientIdentifier: ClientIdentifier.chrome_136,
});
CommonJS is supported too:
const { ClientIdentifier, TLSClient } = require("tls-client-node");
import {
ClientIdentifier,
TLSClient,
} from "tls-client-node";
async function main() {
const client = new TLSClient();
const session = client.session({
clientIdentifier: ClientIdentifier.chrome_136,
});
const response = await session.get("https://tls.peet.ws/api/all");
console.log(response.status, await response.text());
await session.close();
await client.stop();
}
main().catch(console.error);
import { ClientIdentifier, TLSClient } from "tls-client-node";
const client = new TLSClient();
const session = client.session({
clientIdentifier: ClientIdentifier.chrome_136,
timeoutSeconds: 30,
headers: {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
accept: "*/*",
"accept-language": "en-US,en;q=0.9",
"accept-encoding": "gzip, deflate, br",
},
});
const response = await session.get("https://tls.peet.ws/api/all");
console.log(response.status, response.usedProtocol);
await session.close();
await client.stop();
import { ClientIdentifier, fetch } from "tls-client-node";
const response = await fetch("https://example.com", {
clientIdentifier: ClientIdentifier.chrome_136,
headers: {
accept: "text/html",
},
});
console.log(await response.text());
Default local mode is native shared-library loading on supported platforms.
Use managed mode only when you explicitly want the tls-client-api process:
import { TLSClient } from "tls-client-node";
const client = new TLSClient({
runtimeMode: "managed",
});
If you already host tls-client-api yourself, use remote mode:
import { TLSClient } from "tls-client-node";
const client = new TLSClient({
baseUrl: "http://127.0.0.1:8080",
apiKey: "my-auth-key-1",
});
import { TLSClient } from "tls-client-node";
const client = new TLSClient();
const response = await client.request("https://example.com/", {
proxyUrl: "http://user:pass@proxy.example:5959",
followRedirects: true,
headers: {
"user-agent": "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36",
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"accept-language": "en-US,en;q=0.9",
"accept-encoding": "gzip, deflate, br",
},
customTlsClient: {
ja3String: "771,2570-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,2570-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,2570-29-23-24,0",
h2Settings: {
HEADER_TABLE_SIZE: 65536,
MAX_CONCURRENT_STREAMS: 1000,
INITIAL_WINDOW_SIZE: 6291456,
MAX_HEADER_LIST_SIZE: 262144,
},
h2SettingsOrder: [
"HEADER_TABLE_SIZE",
"MAX_CONCURRENT_STREAMS",
"INITIAL_WINDOW_SIZE",
"MAX_HEADER_LIST_SIZE",
],
supportedSignatureAlgorithms: [
"ECDSAWithP256AndSHA256",
"PSSWithSHA256",
"PKCS1WithSHA256",
"ECDSAWithP384AndSHA384",
"PSSWithSHA384",
"PKCS1WithSHA384",
"PSSWithSHA512",
"PKCS1WithSHA512",
],
supportedVersions: ["GREASE", "1.3", "1.2"],
keyShareCurves: ["GREASE", "X25519"],
certCompressionAlgos: ["brotli"],
pseudoHeaderOrder: [":method", ":authority", ":scheme", ":path"],
connectionFlow: 15663105,
headerOrder: ["accept", "user-agent", "accept-encoding", "accept-language"],
priorityFrames: [
{
streamID: 1,
priorityParam: {
streamDep: 1,
exclusive: true,
weight: 1,
},
},
],
headerPriority: {
streamDep: 1,
exclusive: true,
weight: 1,
},
alpnProtocols: ["h2", "http/1.1"],
alpsProtocols: ["h2"],
},
headerOrder: [":method", ":authority", ":scheme", ":path"],
});
TLSClient, create one or more Session instances, and stop the client when finished.Session keeps a tough-cookie jar in sync with request and response cookies. You can inspect URL cookies with session.cookies(url) or serialize the jar with session.exportCookies().byteResponse: true is enabled, matching upstream behavior.ClientIdentifier.tls: illegal parameter or unknown ClientHelloID: Custom-1 throw ERR_CUSTOM_TLS_REJECTED instead of falling back silently.certCompressionAlgo is provided, it is normalized to the upstream certCompressionAlgos field before the request is sent.new TLSClient() is the primary lifecycle model. The top-level fetch() helper uses an isolated temporary client when you do not pass an explicit client or session.This project is distributed under Apache License 2.0 with Commons Clause.
tls-client-node, without separate permission.NOTICE.This is source-available, not OSI open source.
This product includes software developed by Bogdan Finn and contributors via bogdanfinn/tls-client and bogdanfinn/tls-client-api.
FAQs
Node.js client for bogdanfinn/tls-client with native shared-library loading and optional managed runtime support.
The npm package tls-client-node receives a total of 11,150 weekly downloads. As such, tls-client-node popularity was classified as popular.
We found that tls-client-node demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.

Research
More than 140 Mastra npm packages were compromised in a supply chain attack that used a typosquatted dependency to deliver a cross-platform infostealer during installation.