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 🙏

© 2026 – Pkg Stats / Ryan Hefner

ghost-cursor-patchright

v1.0.2

Published

Move your mouse like a human in patchright/playwright, or generate realistic movements on any 2D plane

Readme

Ghost Cursor Patchright

NPM Version License: ISC

Generate realistic, human-like mouse movement data between coordinates or navigate between elements with Patchright. It helps bypass bot detection systems by simulating organic human behavior (mouse movements, mechanical scrolling, and keyboard typing).


🌟 Key Features

🖱️ 1. Human-Like Mouse Movements (Bezier Curves & Fitts's Law)

  • Organic Path Generation: Instead of straight-line trajectories or artificial noise, it uses cubic Bezier curves to calculate natural curved paths between coordinates.
  • Fitts's Law Integration: Dynamically scales speed based on the target element's size and distance. Smaller or further targets result in slower, more deliberate movements, mimicking human motor control.
  • Smart Overshooting & Re-adjustment: For distant movements, the cursor can overshoot or slightly miss the target element, followed by a minor correction movement to land on the element, imitating human hand inertia.
  • Randomized Coordinates: When hovering over or clicking an element, it picks a randomized point within the element boundaries (adjustable via padding) instead of always clicking the dead center.

⌨️ 2. Natural Keyboard Input Emulation

  • QWERTY Layout Typo Emulation: Key strokes are typed character-by-character. Based on the QWERTY layout proximity map, the cursor will occasionally type neighboring keys (e.g., typing 'w' instead of 'e').
  • Self-Correction (Backspace): When a typo occurs, the typing halts, pauses briefly (simulating the human "oops" moment), presses backspace to delete the typo, and then continues with the correct text.
  • Randomized Key Delays: Simulates variable typing speeds by randomizing the delay between keystrokes (e.g., average delay with standard deviation variations).

🔄 3. Resilient Browser Integration

  • CDP Session Auto-Recovery: Automatically monitors, re-establishes, and re-attaches the Chrome DevTools Protocol (CDP) session during frame or page transitions, avoiding typical "detached session" crashes.
  • Mechanical Wheel Scrolling: Simulates organic wheel scrolling by applying randomized 5ms to 15ms delay steps between mouse-wheel ticks rather than executing instant jumps.
  • Universal Selectors: Supports both standard CSS selectors and complex XPath expressions natively.

🚀 Installation

# using yarn
yarn add ghost-cursor-patchright

# using npm
npm install ghost-cursor-patchright

📖 Quick Start

1. Generating Movement Path Data

You can generate human-like coordinates on a 2D plane without launching a browser.

import { path } from "ghost-cursor-patchright"

const from = { x: 100, y: 100 }
const to = { x: 600, y: 700 }

const route = path(from, to)
/**
 * Returns:
 * [
 *   { x: 100, y: 100 },
 *   { x: 108.75, y: 102.83 },
 *   ...
 * ]
 */

2. Browser Navigation and Interaction

Control your Patchright browser session with realistic movements.

import { GhostCursor } from "ghost-cursor-patchright"
import { chromium } from "patchright"

const run = async (url) => {
  const browser = await chromium.launch({ headless: false })
  const page = await browser.newPage()
  
  // Initialize the cursor with visual debugging helper enabled
  const cursor = await GhostCursor.create(page, { visible: true })
  
  await page.goto(url)
  
  // Moves mouse to element and clicks it
  await cursor.click("#sign-up-button")
  
  // Types text character-by-character with 10% typo ratio
  await cursor.type("#email-input", "[email protected]", { typoRatio: 0.1 })
}

🛠️ API Reference

Creation Method

GhostCursor.create(page: Page, options?: GhostCursorOptions)

Creates the ghost cursor that wraps your Page session.

GhostCursorOptions Config

| Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | start | Vector | { x: 0, y: 0 } | Starting coordinate of the cursor. | | performRandomMoves | boolean | false | Actively trigger random movements on idle. | | visible | boolean | false | Renders a red dot on the browser representing the cursor. | | defaultOptions | DefaultOptions | {} | Configure global default configurations for click, move, type, etc. |


Core Instance Methods

click(selector?: string | ElementHandle, options?: ClickOptions)

Moves the mouse to the specified selector or element handle and clicks it.

ClickOptions (Extends MoveOptions & ScrollIntoViewOptions)

| Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | hesitate | number | 0 | Delay before initiating the click in milliseconds. | | waitForClick | number | 0 | Delay between mousedown and mouseup (click speed) in ms. | | moveDelay | number | 2000 | Post-movement delay in ms before clicking. | | button | 'left' \| 'right' \| 'middle' | 'left' | Mouse button to press. | | clickCount | number | 1 | Number of times to click. |

move(selector: string | ElementHandle, options?: MoveOptions)

Smoothly moves the cursor to the target element.

MoveOptions (Extends ScrollIntoViewOptions)

| Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | paddingPercentage | number | 0 | Percentage of inner padding to constrain target coordinates. 100 always targets the absolute center. | | destination | Vector | undefined | Absolute coordinates override to bypass random calculation. | | moveDelay | number | 0 | Delay after movement finishes in ms. | | randomizeMoveDelay | boolean | true | Randomizes the moveDelay from 0 to the set value. | | moveSpeed | number | random | Speed factor of the mouse movement. | | overshootThreshold | number | 500 | Distance limit above which overshoot simulation triggers. |

type(selector: string | ElementHandle, text: string, options?: TypeOptions)

Clicks the element to focus and types the text.

TypeOptions

| Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | delay | number | 80 | Average delay between keystrokes in ms. | | randomizeDelay | boolean | true | Randomizes typing speed to simulate human rhythm. | | typoRatio | number | 0.0 | Probability (from 0.0 to 1.0) of making a QWERTY neighbor typo. |

scrollIntoView(selector: string | ElementHandle, options?: ScrollIntoViewOptions)

Scrolls the target element into the viewport smoothly if not already visible.

ScrollIntoViewOptions

| Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | scrollSpeed | number | 100 | Scrolling speed (0 to 100). 100 performs instant scroll. | | scrollDelay | number | 200 | Delay after scroll completes. | | inViewportMargin | number | 0 | Extra padding margin in pixels when validating element visibility. |

scroll(delta: Partial<Vector>, options?: ScrollOptions)

Scrolls the viewport page by a specified x and y distance offset.

scrollTo(destination: Partial<Vector> | 'top' | 'bottom' | 'left' | 'right', options?: ScrollOptions)

Scrolls the viewport to the absolute target position or a viewport edge.

getLocation()

Returns the current cursor coordinates ({ x: number, y: number }).


🪵 Debug Logging

Enable comprehensive debug logs by setting the environment variable:

# Bash/Terminal
DEBUG="ghost-cursor:*"

# Windows PowerShell
$env:DEBUG = "ghost-cursor:*"

📄 License

Released under the ISC License.