PacketStream integration

Using PacketStream residential proxies with Puppeteer

Route Puppeteer through PacketStream with a loopback bridge that keeps proxy credentials away from destination authentication challenges.

Run Chrome automation through PacketStream without giving proxy credentials to the pages you visit. A loopback Proxy Chain bridge sends them only to PacketStream’s upstream proxy.

Configure

Install Puppeteer and Proxy Chain, then set your PacketStream credentials:

npm install proxy-chain puppeteer
export PACKETSTREAM_USER='your_username'
export PACKETSTREAM_AUTH_KEY='your_auth_key'

Create packetstream_puppeteer.mjs:

import { anonymizeProxy, closeAnonymizedProxy } from "proxy-chain";
import puppeteer from "puppeteer";

const username = process.env.PACKETSTREAM_USER;
const authKey = process.env.PACKETSTREAM_AUTH_KEY;

if (!username || !authKey) {
  throw new Error("Set PACKETSTREAM_USER and PACKETSTREAM_AUTH_KEY");
}

const upstreamProxy = new URL("https://proxy.packetstream.io:31111");
upstreamProxy.username = username;
upstreamProxy.password = authKey;

const localProxyUrl = await anonymizeProxy(upstreamProxy.href);
let browser;

try {
  browser = await puppeteer.launch({
    args: [`--proxy-server=${localProxyUrl}`],
  });
  const page = await browser.newPage();
  await page.goto("https://ipinfo.io/json", {
    waitUntil: "domcontentloaded",
    timeout: 30_000,
  });
  console.log(await page.$eval("body", (body) => JSON.parse(body.innerText)));
} finally {
  try {
    if (browser) await browser.close();
  } finally {
    await closeAnonymizedProxy(localProxyUrl, true);
  }
}

Proxy Chain binds the temporary unauthenticated proxy to 127.0.0.1 and sends the PacketStream credentials only to the upstream proxy. This avoids Puppeteer’s page-wide authentication handler, which can also answer a destination’s authentication challenge.

Use this bridge only on a single-user machine. On a shared host, another local process could discover the temporary port and use it while the script runs; use Playwright there so the browser receives scoped proxy credentials directly.

For SOCKS5, initialize upstreamProxy with socks5://proxy.packetstream.io:31113 and keep the same username and auth-key setters.

Verify your exit

Run node packetstream_puppeteer.mjs and inspect the printed ipinfo.io object for the observed ip and country.

Country targeting and sticky sessions

Set the modified password before calling anonymizeProxy:

upstreamProxy.password = `${authKey}_country-US_session-browser42`;

Keep the session label non-sensitive and use a different label for an independent concurrent workflow.

Troubleshooting

  • Do not pass PacketStream credentials to page.authenticate. It can answer destination authentication challenges as well as proxy challenges.
  • Always close the anonymized proxy. It listens only on loopback, but leaving it open also leaves its upstream credentials usable by local processes.
  • Close and relaunch a browser when a test specifically needs a new proxy connection. New pages can share pooled connections.

See proxy troubleshooting for authentication, browser timeouts, TLS, and rotation checks.

Ready to run Puppeteer through PacketStream? Create an account to get the proxy username and auth key used in the example above.
Create account