Skip to content

πŸ†” Identity & Profile β€” Hardware Fingerprint & Browser Settings ​

Piggy generates a persistent hardware fingerprint and browser profile on first run. This ensures consistent identity across restarts and bypasses fingerprint-based bot detection.

⚠️ Version Requirement: Binary v0.1.14+ | Library v0.0.21+


Overview ​

Two files control Piggy's identity in your working directory:

FilePurposeEdit Safely?
identity.jsonHardware fingerprint (CPU, RAM, GPU, timezone, noise seeds)❌ No (but you can delete it)
profile.jsonBrowser settings (UA, images, JS, localStorage)βœ… Yes

Look at these files. This is why Cloudflare trusts us.


File Locations ​

Both files are saved in your working directory (where your script runs):

/home/user/my-scraper/
β”œβ”€β”€ nothing-browser-headless
β”œβ”€β”€ identity.json          ← Hardware fingerprint (DO NOT EDIT)
β”œβ”€β”€ profile.json           ← Browser settings (SAFE TO EDIT)
β”œβ”€β”€ cookies.json           ← Persistent cookies
β”œβ”€β”€ ws.json                ← WebSocket frames (opt-in)
└── pings.json             ← Ping log (opt-in)

identity.json β€” Hardware Fingerprint ​

What It Looks Like (Real Example) ​

json
{
    "audio_seed": 0.9924607627410863,
    "canvas_seed": 0.1052501868035769,
    "chrome_version": 124,
    "cpu_cores": 4,
    "font_seed": 0.3462124848953487,
    "generated_at": "2026-05-18T13:48:00Z",
    "gpu_renderer": "ANGLE (Intel, Mesa Intel(R) HD Graphics 3000 (SNB GT2), OpenGL 4.6)",
    "gpu_vendor": "Google Inc. (Intel)",
    "identity_id": "2ed6562e-0db2-4603-a05c-6071b0a6fc10",
    "language": "en-US",
    "os": "Windows NT 10.0; Win64; x64",
    "pixel_ratio": 1,
    "platform": "Win32",
    "ram_gb": 8,
    "screen_h": 768,
    "screen_w": 1366,
    "sec_ch_ua": "\"Google Chrome\";v=\"124\", \"Chromium\";v=\"124\", \"Not-A.Brand\";v=\"99\"",
    "timezone": "Africa/Nairobi",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "webgl_seed": 0.8038608544726111
}

What Each Field Means ​

FieldSourcePurpose
cpu_coresstd::thread::hardware_concurrency()Browser fingerprint
ram_gbSystem memory detectionBrowser fingerprint
screen_w / screen_hPrimary display resolutionViewport spoofing
pixel_ratioDevice pixel ratioScreen fingerprint
gpu_vendorOpenGL queryWebGL spoofing
gpu_rendererOpenGL queryWebGL spoofing
timezoneSystem timezoneTimezone spoofing
os / platformOS detectionPlatform fingerprint
user_agentBuilt from identityHTTP + JS fingerprint
sec_ch_uaChrome Client HintsModern browser fingerprint
canvas_seedRandom (0-1)Canvas fingerprint noise
audio_seedRandom (0-1)Audio fingerprint noise
webgl_seedRandom (0-1)WebGL fingerprint noise
font_seedRandom (0-1)Font fingerprint noise
identity_idUUIDUnique identity tracking
generated_atISO timestampWhen this identity was created

Why Cloudflare Trusts Us ​

Look at this file. It's not fake. It's not generic.

"gpu_renderer": "ANGLE (Intel, Mesa Intel(R) HD Graphics 3000 (SNB GT2), OpenGL 4.6)"

That's a real GPU renderer string. Not "Chrome". Not "HeadlessChrome". Real hardware.

"os": "Windows NT 10.0; Win64; x64"
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."

Real OS. Real Windows UA. Not a generic Linux headless string.

"cpu_cores": 4
"ram_gb": 8
"screen_w": 1366
"screen_h": 768

Real hardware specs from YOUR machine. Not a datacenter VM default.

This is why Cloudflare trusts Piggy. The fingerprint looks like a real person's computer β€” because it IS a real person's computer.

⚠️ DO NOT EDIT THIS FILE ​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                 β”‚
β”‚   WARNING: Do NOT modify identity.json manually                β”‚
β”‚                                                                 β”‚
β”‚   - Breaks fingerprint consistency                             β”‚
β”‚   - May make browser detectable                                β”‚
β”‚   - Invalid values cause crashes                               β”‚
β”‚                                                                 β”‚
β”‚   Delete it β†’ Piggy regenerates fresh identity on next run     β”‚
β”‚   Keep it β†’ Consistent fingerprint across restarts             β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Reset Identity ​

bash
# Stop Piggy
pkill nothing-browser-headless

# Delete identity.json
rm identity.json

# Restart β€” new identity generated
./nothing-browser-headless

Delete it as much as you want. Piggy will regenerate a fresh identity on next run. Looking at these files, you'll understand why Cloudflare trusts us.


profile.json β€” Browser Settings ​

What It Looks Like ​

json
{
    "imagesEnabled": true,
    "javascriptEnabled": true,
    "language": "en-US",
    "localStorageEnabled": true,
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "webglEnabled": true
}

What Each Field Does ​

FieldTypeDescription
imagesEnabledbooleanLoad images on page
javascriptEnabledbooleanExecute JavaScript
languagestringBrowser language (Accept-Language header)
localStorageEnabledbooleanEnable localStorage API
userAgentstringBrowser user agent string
webglEnabledbooleanEnable WebGL (for fingerprinting)

βœ… SAFE TO EDIT ​

You can modify profile.json while Piggy is running:

bash
# 1. Stop or pause scraper
# 2. Edit profile.json
nano profile.json

# 3. If running, reload
await piggy.site.session.reload();

# 4. Changes take effect immediately

Common Profile Tweaks ​

Disable Images (Faster Scraping) ​

json
{
    "imagesEnabled": false
}

Change Language ​

json
{
    "language": "ja-JP",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}

Note: Language change alone doesn't fully spoof locale. For full locale spoofing, you'd also need to modify identity.json (which you shouldn't). Delete identity.json and restart to regenerate with different language.


How Piggy Uses These Files ​

On First Run ​

  1. identity.json is generated β€” reads real hardware values from your system
  2. profile.json is created β€” built from identity values
  3. Fingerprint spoofing is active β€” injected at DocumentCreation

On Subsequent Runs ​

  1. Load existing identity.json β€” same fingerprint across restarts
  2. Load profile.json β€” same browser settings
  3. Continue scraping with consistent identity

Hot Reload ​

typescript
// After editing profile.json
await piggy.site.session.reload();
console.log("Profile reloaded!");

Real-World Examples ​

Example 1: Check Your Identity ​

typescript
import { readFileSync } from "fs";

const identity = JSON.parse(readFileSync("./identity.json", "utf-8"));
console.log("Your hardware fingerprint:");
console.log(`  CPU Cores: ${identity.cpu_cores}`);
console.log(`  RAM: ${identity.ram_gb}GB`);
console.log(`  Screen: ${identity.screen_w}x${identity.screen_h}`);
console.log(`  GPU: ${identity.gpu_renderer}`);
console.log(`  Timezone: ${identity.timezone}`);
console.log(`  Identity ID: ${identity.identity_id}`);

Example 2: Persistent Identity Across Restarts ​

typescript
// First run β€” identity.json generated
// Second run β€” same identity loaded automatically

await piggy.launch();

const fingerprint = await piggy.site.evaluate(() => ({
  userAgent: navigator.userAgent,
  platform: navigator.platform,
  webglVendor: document.createElement('canvas').getContext('webgl')?.getParameter(37445)
}));

console.log("Same fingerprint every run:", fingerprint);

Example 3: Different Identities for Different Projects ​

bash
# Project A β€” uses its own identity
cd /home/user/project-a
./nothing-browser-headless  # Generates identity.json here

# Project B β€” separate identity
cd /home/user/project-b
./nothing-browser-headless  # Generates different identity.json here

Each project directory has its own identity.json and profile.json.

Example 4: Disable Images for Faster Scraping ​

bash
# Edit profile.json
nano profile.json
json
{
    "imagesEnabled": false,
    "javascriptEnabled": true,
    "language": "en-US",
    "localStorageEnabled": true,
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...",
    "webglEnabled": true
}
typescript
// Reload without restart
await piggy.site.session.reload();

// Images are now blocked β€” pages load faster
await piggy.site.navigate("https://image-heavy-site.com");

File Format Specifications ​

identity.json ​

typescript
interface Identity {
  audio_seed: number;           // 0-1 random seed for audio fingerprint
  canvas_seed: number;          // 0-1 random seed for canvas fingerprint
  chrome_version: number;       // Chrome version to spoof (e.g., 124)
  cpu_cores: number;            // 1-128
  font_seed: number;            // 0-1 random seed for font fingerprint
  generated_at: string;         // ISO timestamp
  gpu_renderer: string;         // Full GPU renderer string
  gpu_vendor: string;           // GPU vendor string
  identity_id: string;          // UUID v4
  language: string;             // BCP-47 language tag
  os: string;                   // Operating system string
  pixel_ratio: number;          // Device pixel ratio (1, 1.25, 1.5, 2, etc.)
  platform: string;             // Platform string (Win32, MacIntel, Linux x86_64)
  ram_gb: number;               // RAM in GB (0.5-512)
  screen_h: number;             // Screen height in pixels
  screen_w: number;             // Screen width in pixels
  sec_ch_ua: string;            // Sec-Ch-Ua header value
  timezone: string;             // IANA timezone (e.g., "Africa/Nairobi")
  user_agent: string;           // Full user agent string
  webgl_seed: number;           // 0-1 random seed for WebGL fingerprint
}

profile.json ​

typescript
interface Profile {
  imagesEnabled: boolean;       // Load images
  javascriptEnabled: boolean;   // Execute JavaScript
  language: string;             // Browser language
  localStorageEnabled: boolean; // Enable localStorage
  userAgent: string;            // User agent string
  webglEnabled: boolean;        // Enable WebGL
}

Troubleshooting ​

"identity.json not being generated" ​

Cause: Binary version too old or permissions issue

Fix:

bash
# Check binary version
./nothing-browser-headless --version

# Ensure write permissions in current directory
chmod 755 .

"Different fingerprint on each run" ​

Cause: identity.json deleted or not readable

Fix: Keep identity.json β€” don't delete it between runs

"Website still detects automation" ​

Cause: Some bot detection looks for other signals

Check your fingerprint:

typescript
const fingerprint = await piggy.site.evaluate(() => ({
  webdriver: navigator.webdriver,
  plugins: navigator.plugins.length,
  languages: navigator.languages,
  webglVendor: document.createElement('canvas').getContext('webgl')?.getParameter(37445)
}));

console.log(fingerprint);
// webdriver: undefined βœ…
// plugins: 3 βœ…
// webglVendor: "Google Inc. (Intel)" βœ…

"profile.json changes not applying" ​

Cause: Need to reload after editing

Fix:

typescript
await piggy.site.session.reload();

Why This Beats Puppeteer ​

AspectPuppeteerPiggy
FingerprintGeneric "HeadlessChrome"Real hardware from YOUR machine
GPU stringMissing or fakeReal ANGLE renderer
Screen resolutionFixed 800x600Your actual screen size
CPU/RAMNot spoofedYour real CPU cores and RAM
ConsistencySame fake fingerprint for everyoneUnique per user
Cloudflare❌ Blockedβœ… Passes

This is why Cloudflare trusts us. We don't look like a bot. We look like YOU.


Next Steps ​


Nothing Ecosystem Β· Ernest Tech House Β· Kenya Β· 2026

MIT Licensed | Built by Ernest Tech House Β· Kenya Β· 2026