npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

persona-browser

v1.0.1

Published

Minimal automated browser control with network logging using Chrome DevTools Protocol

Downloads

17

Readme

PersonaBrowser

Exceptionally lightweight automated browser control with network logging using Chrome DevTools Protocol. Built to pass advanced antibot systems including Akamai, Kasada, Shape, and Cloudflare.

Installation

npm install persona-browser

Quick Start

CommonJS

const { PersonaBrowser } = require('persona-browser');
// or
const PersonaBrowser = require('persona-browser').default;

async function example() {
  const browser = new PersonaBrowser({
    headless: false,
    windowSize: { width: 1200, height: 800 }
  });

  await browser.launch();
  await browser.navigate('https://example.com');
  
  // Click a button
  await browser.clickButton('#submit');
  
  // Type text
  await browser.typeText('Hello, World!');
  
  // Take a screenshot
  await browser.screenshot('screenshot.png');
  
  // Get network log
  const networkLog = browser.getNetworkLog();
  console.log('Network requests:', networkLog);
  
  await browser.close();
}

example();

ES Modules

import PersonaBrowser from 'persona-browser';
// or
import { PersonaBrowser } from 'persona-browser';

async function example() {
  const browser = new PersonaBrowser({
    headless: false,
    windowSize: { width: 1200, height: 800 }
  });

  await browser.launch();
  await browser.navigate('https://example.com');
  await browser.close();
}

example();

Features

  • Exceptionally Lightweight - Minimal footprint (~62KB package size) with zero unnecessary dependencies
  • 🛡️ Antibot Bypass - Successfully passes advanced antibot systems including Akamai, Kasada, Shape, and Cloudflare
  • 🚀 Minimal API - Simple, intuitive interface
  • 🌐 Network Logging - Track all network requests and responses
  • Accessibility Support - Find elements using accessibility tree
  • 📸 Screenshots - Capture page screenshots
  • ⌨️ Keyboard Input - Type text and press keys
  • 🖱️ Mouse Actions - Click, double-click elements
  • 📜 Multiple Pages - Create and manage multiple tabs
  • 🔍 Element Finding - Find elements by text, selector, or accessibility tree
  • 🎯 Request Interception - Modify or block network requests

API Documentation

Constructor

new PersonaBrowser(options?: PersonaBrowserConfig)

Options:

  • headless?: boolean - Run browser in headless mode (default: true)
  • windowSize?: { width: number, height: number } - Browser window size
  • userDataDir?: string - Custom Chrome user data directory

Methods

Navigation

  • launch() - Launch Chrome browser
  • navigate(url: string, timeout?: number) - Navigate to a URL
  • reload(options?) - Reload the current page
  • goBack(options?) - Navigate back
  • goForward(options?) - Navigate forward
  • waitForPageLoad(timeout?: number) - Wait for page to load
  • waitForNavigation(options?) - Wait for navigation with options

Element Interaction

  • clickButton(selector: string) - Click element by selector
  • clickElementByText(text: string, options?) - Click element by text
  • clickLinkByIndex(index: number) - Click link by index
  • clickLinkByText(text: string, options?) - Click link by text
  • doubleClick(selector: string) - Double click element
  • typeText(text: string, minDelay?: number, maxDelay?: number) - Type text
  • fillInput(selector: string, value: string) - Fill input field
  • clearInput(selector: string) - Clear input field
  • pressKey(key: string, options?) - Press a keyboard key

Element Finding

  • $(selector: string) - Query selector (returns ElementHandle or null)
  • $$(selector: string) - Query selector all (returns ElementHandle[])
  • waitForSelector(selector: string, options?) - Wait for selector
  • findLinks() - Find all links using accessibility tree
  • findTextElements(options?) - Find text elements using accessibility tree

Accessibility

  • getAccessibilityTree(options?) - Get full accessibility tree
  • getPartialAccessibilityTree(nodeId: number, options?) - Get partial tree
  • queryAccessibilityTree(nodeId: number, options?) - Query tree by criteria
  • flattenAccessibilityTree(tree) - Flatten tree to list
  • findNodesByRole(tree, role: string) - Find nodes by role
  • findNodesByName(tree, name: string) - Find nodes by name

Network

  • getNetworkLog() - Get all network requests
  • saveNetworkLog(filename?: string) - Save network log to file
  • clearNetworkLog() - Clear network log
  • waitForResponse(predicate, timeout?) - Wait for matching response
  • waitForRequest(predicate, timeout?) - Wait for matching request
  • setRequestInterception(interceptor) - Enable request interception
  • disableRequestInterception() - Disable request interception

Page Management

  • newPage() - Create a new page/tab
  • getPages() - Get all open pages
  • closePage(targetId?) - Close a specific page
  • screenshot(filepath?, options?) - Take screenshot
  • scrollBy(options?) - Scroll page or container
  • url() - Get current URL
  • title() - Get page title
  • getCookies() - Get all cookies
  • setCookies(cookies: any[]) - Set cookies
  • executeJS(expression: string) - Execute JavaScript

Cleanup

  • close(saveLog?: boolean) - Close browser and optionally save log

Examples

Basic Navigation

const browser = new PersonaBrowser({ headless: false });
await browser.launch();
await browser.navigate('https://example.com');
await browser.close();

Form Filling

await browser.navigate('https://example.com/form');
await browser.fillInput('#name', 'John Doe');
await browser.fillInput('#email', '[email protected]');
await browser.clickButton('#submit');
await browser.waitForPageLoad();

Network Monitoring

await browser.navigate('https://example.com');

// Wait for specific API response
const response = await browser.waitForResponse(
  (r) => r.url.includes('/api/data') && r.status === 200
);

// Get all network requests
const log = browser.getNetworkLog();
console.log(`Captured ${log.length} requests`);

// Save to file
await browser.saveNetworkLog('network.json');

Request Interception

// Block ads
browser.setRequestInterception(async (request) => {
  if (request.url.includes('ads')) {
    return { url: 'about:blank' }; // Block
  }
});

// Modify headers
browser.setRequestInterception(async (request) => {
  return {
    headers: { ...request.headers, 'X-Custom': 'value' }
  };
});

Multiple Pages

const page1 = await browser.newPage();
await page1.navigate('https://example.com');

const page2 = await browser.newPage();
await page2.navigate('https://google.com');

// Switch between pages
const pages = browser.getPages();

License

MIT

Author

Cole Banman