Fingerprint tooling is useful only when it is treated as a privacy and testing control, not a magic invisibility layer. Browser fingerprints combine device, network, rendering, storage, and behavior signals. Safer use starts with a clear test purpose, limited data, and separation from real identities.
What is fingerprint-suite#
fingerprint-suite is a TypeScript toolkit from Apify that helps you generate and inject realistic browser fingerprints into automation tools like Playwright and Puppeteer. In plain terms: it makes your scraper look more like a normal browser session instead of an obvious bot.
Why this matters: many websites now check browser fingerprints in addition to IP address. They can inspect things like user agent strings, language, screen size, timezone, and JavaScript APIs. If those signals don’t line up, your scraper is easier to detect and block. fingerprint-suite helps keep those signals consistent.
This tool is useful for technically minded users who run web scrapers, privacy-focused automation, or testing workflows where browser identity needs to look believable. It is not a VPN and it does not hide your IP by itself, but it complements VPNs, proxies, and good OPSEC by making the browser layer less suspicious.
Installation#
You need a recent Node.js runtime first. The package is published as a set of modules, with fingerprint-injector being the main entry point for Playwright and Puppeteer integration.
1) Install Node.js#
Linux
If you use nvm, this is the easiest path:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --lts
nvm use --lts
node -v
npm -v
macOS
With nvm, the process is the same as Linux:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --lts
nvm use --lts
node -v
npm -v
Windows
On Windows, install the Node.js LTS release with winget or the official installer:
winget install OpenJS.NodeJS.LTS
node -v
npm -v
2) Create a project#
mkdir fingerprint-demo
cd fingerprint-demo
npm init -y
3) Install the packages#
If you use Playwright:
npm install fingerprint-injector playwright
npx playwright install
If you use Puppeteer:
npm install fingerprint-injector puppeteer
If you want to run TypeScript files directly during development, install a runner like tsx:
npm install -D typescript tsx @types/node
Basic Configuration#
The simplest pattern is:
- launch the browser
- create an injected context or page
- choose a fingerprint profile
- browse normally
Playwright example#
Save this as playwright-demo.ts:
import { chromium } from 'playwright';
import { newInjectedContext } from 'fingerprint-injector';
async function main() {
const browser = await chromium.launch({ headless: false });
const context = await newInjectedContext(browser, {
fingerprintOptions: {
devices: ['desktop'],
operatingSystems: ['windows'],
},
newContextOptions: {
locale: 'en-US',
timezoneId: 'America/New_York',
},
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log('Title:', await page.title());
await browser.close();
}
main().catch(console.error);
Run it with:
npx tsx playwright-demo.ts
Puppeteer example#
Save this as puppeteer-demo.ts:
import puppeteer from 'puppeteer';
import { newInjectedPage } from 'fingerprint-injector';
async function main() {
const browser = await puppeteer.launch({ headless: false });
const page = await newInjectedPage(browser, {
fingerprintOptions: {
devices: ['mobile'],
operatingSystems: ['ios'],
},
});
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
console.log('Title:', await page.title());
await browser.close();
}
main().catch(console.error);
Run it with:
npx tsx puppeteer-demo.ts
The main idea is that fingerprintOptions gives the generator boundaries. For example, you can ask for a mobile fingerprint on iOS or a desktop fingerprint on Windows. newContextOptions lets you align the browser context with that identity.
Common Use Cases#
1) Scraping sites that block obvious automation#
If a site aggressively filters bots, a clean browser fingerprint often helps more than random user-agent swapping. Here’s a typical Playwright setup for a desktop scraper:
import { chromium } from 'playwright';
import { newInjectedContext } from 'fingerprint-injector';
async function scrape() {
const browser = await chromium.launch({ headless: true });
const context = await newInjectedContext(browser, {
fingerprintOptions: {
devices: ['desktop'],
operatingSystems: ['windows'],
},
newContextOptions: {
locale: 'en-US',
timezoneId: 'America/Chicago',
},
});
const page = await context.newPage();
await page.goto('https://shop.example.com/products', { waitUntil: 'domcontentloaded' });
const titles = await page.locator('h2.product-title').allTextContents();
console.log(titles);
await browser.close();
}
scrape();
This works best when your proxy, locale, and timezone are consistent with the fingerprint.
2) Testing mobile layouts and mobile-only behavior#
Sometimes you want a mobile-like browser identity for QA, research, or scraping pages that serve different content to phones. In that case, use a mobile fingerprint and a mobile viewport:
import { chromium } from 'playwright';
import { newInjectedContext } from 'fingerprint-injector';
async function mobileTest() {
const browser = await chromium.launch({ headless: false });
const context = await newInjectedContext(browser, {
fingerprintOptions: {
devices: ['mobile'],
operatingSystems: ['ios'],
},
newContextOptions: {
viewport: { width: 390, height: 844 },
isMobile: true,
hasTouch: true,
locale: 'en-US',
timezoneId: 'America/Los_Angeles',
},
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await browser.close();
}
mobileTest();
This is useful when you need the browser identity to match the screen shape and input model.
3) Upgrading an existing Puppeteer scraper#
If you already have Puppeteer code, you can often replace browser.newPage() with newInjectedPage() and keep the rest of your scraper the same:
import puppeteer from 'puppeteer';
import { newInjectedPage } from 'fingerprint-injector';
async function existingScraper() {
const browser = await puppeteer.launch({ headless: true });
const page = await newInjectedPage(browser, {
fingerprintOptions: {
devices: ['desktop'],
operatingSystems: ['linux'],
},
});
await page.goto('https://news.example.com', { waitUntil: 'networkidle2' });
const headlines = await page.$eval('article h2', nodes =>
nodes.map(node => node.textContent?.trim()).filter(Boolean)
);
console.log(headlines);
await browser.close();
}
existingScraper();
That makes adoption easier if your project already uses Puppeteer and you do not want to rewrite everything.
Tips and Gotchas#
fingerprint-suiteimproves browser realism, but it does not make you invisible. Sites can still use IP reputation, cookies, TLS signals, and behavior analysis.- Match the fingerprint to the rest of the session. If you use a mobile fingerprint, do not pair it with a huge desktop viewport or a mismatched timezone.
- Use a fresh browser context for new identities. Reusing the same context across unrelated targets can leak state and make tracking easier.
- Keep your browser automation library updated. Fingerprinting and anti-bot checks change frequently, and the latest
fingerprint-suiterelease may update the model used to generate fingerprints. - For debugging, run in headful mode first:
const browser = await chromium.launch({ headless: false });
- If you use proxies, choose a proxy location that roughly matches the locale and timezone you set in the browser context.
- Start small. Test one site, one fingerprint, and one workflow before scaling up to many targets.
Conclusion#
fingerprint-suite is a practical way to make Playwright and Puppeteer scrapers look less robotic without hand-crafting every browser signal yourself. It is a good fit for beginners who want cleaner automation, better privacy hygiene, and fewer fingerprint-related blocks.
Related reading#
- Start with the privacy guides.
- Read browser hardening without breakage for user-facing fingerprint controls.
- Use the security guides to review automation and tooling risk.
What should readers decide before using fingerprint tooling?#
Readers should decide whether they are testing site compatibility, reducing unwanted correlation, or automating research. Each goal needs different constraints, and using real accounts or sensitive sessions inside experiments can create more risk than it removes.
Definition#
- Browser fingerprint - a combination of browser, device, rendering, network, storage, and behavior signals that can help sites recognize a session without a traditional cookie.
Comparison#
| Use case | Use when | Watch out for |
|---|---|---|
| Compatibility testing | You need to see how sites react to browser traits | Do not mix test profiles with real accounts |
| Privacy research | You need to reduce correlation signals | Unusual configurations can become more unique |
FAQ#
Does changing a fingerprint make a user anonymous?#
No. It may change some browser signals, but accounts, IP behavior, payments, timing, and device habits can still link activity.
What is the safest starting point?#
Use separate test profiles, avoid real accounts, keep datasets minimal, and document which signals the tool changes before relying on results.