Implementation:Puppeteer Puppeteer JSHandle
| Sources | packages/puppeteer-core/src/api/JSHandle.ts |
|---|---|
| Domains | JavaScript Runtime, Object References, Remote Evaluation |
| Last Updated | 2026-02-12 |
Overview
JSHandle is the abstract base class that represents a reference to a JavaScript object in the browser's runtime, preventing the referenced object from being garbage-collected until the handle is disposed.
Description
The JSHandle<T> class provides a mechanism for holding references to JavaScript objects living in the browser context. These handles prevent the referenced objects from being garbage-collected unless the handle is explicitly disposed via dispose(). Handles are auto-disposed when their associated frame navigates away or the parent execution context is destroyed.
The class is decorated with @moveable, enabling ownership transfer of handle references. It provides two core evaluation methods: evaluate() runs a function with the handle's referenced object as the first argument and returns a deserialized result, while evaluateHandle() does the same but returns a new JSHandle to the result instead.
Property access is supported through getProperty() for fetching a single property and getProperties() for retrieving a map of all enumerable properties. The jsonValue() method returns a vanilla serializable representation of the referenced object (throwing on circular references). The asElement() method returns the handle as an ElementHandle if applicable, or null otherwise.
The class also exposes remoteObject() for direct access to the underlying CDP Protocol.Runtime.RemoteObject, and implements both synchronous and asynchronous dispose symbols for resource cleanup.
Usage
JSHandle instances are obtained through evaluation methods such as Page.evaluateHandle() or JSHandle.evaluateHandle(). Handles can be passed as arguments to any evaluation function (Page.$eval, Page.evaluate, Page.evaluateHandle) where they resolve to their referenced objects.
Code Reference
Source Location
packages/puppeteer-core/src/api/JSHandle.ts
Signature
@moveable
export abstract class JSHandle<T = unknown> {
abstract get realm(): Realm;
abstract get disposed(): boolean;
async evaluate<Params extends unknown[], Func extends EvaluateFuncWith<T, Params>>(
pageFunction: Func | string, ...args: Params
): Promise<Awaited<ReturnType<Func>>>;
async evaluateHandle<Params extends unknown[], Func extends EvaluateFuncWith<T, Params>>(
pageFunction: Func | string, ...args: Params
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
async getProperty<K extends keyof T>(propertyName: HandleOr<K>): Promise<HandleFor<T[K]>>;
async getProperties(): Promise<Map<string, JSHandle>>;
abstract jsonValue(): Promise<T>;
abstract asElement(): ElementHandle<Node> | null;
abstract dispose(): Promise<void>;
abstract toString(): string;
abstract get id(): string | undefined;
abstract remoteObject(): Protocol.Runtime.RemoteObject;
}
Import
import type {JSHandle} from 'puppeteer-core/src/api/JSHandle.js';
I/O Contract
Inputs
| Parameter | Type | Description |
|---|---|---|
| pageFunction (evaluate) | string | Function to evaluate with the handle as first argument |
| args (evaluate) | Params |
Additional arguments passed to the function |
| pageFunction (evaluateHandle) | string | Function to evaluate, returning a handle to the result |
| args (evaluateHandle) | Params |
Additional arguments passed to the function |
| propertyName (getProperty) | HandleOr<K> |
Name of the property to fetch |
Outputs
| Method | Return Type | Description |
|---|---|---|
| evaluate() | Promise<Awaited<ReturnType<Func>>> |
Deserialized return value of the evaluated function |
| evaluateHandle() | Promise<HandleFor<Awaited<ReturnType<Func>>>> |
A handle to the return value of the evaluated function |
| getProperty() | Promise<HandleFor<T[K]>> |
A handle to the specified property |
| getProperties() | Promise<Map<string, JSHandle>> |
Map of property names to handles for all enumerable properties |
| jsonValue() | Promise<T> |
Serializable representation of the referenced object |
| asElement() | null | The handle as an ElementHandle, or null |
| remoteObject() | Protocol.Runtime.RemoteObject |
The underlying CDP remote object |
| disposed | boolean |
Whether the handle has been disposed |
| id | undefined | The handle identifier |
Usage Examples
// Create a handle to the window object
const windowHandle = await page.evaluateHandle(() => window);
// Evaluate a function with the handle as first argument
const handle = await page.evaluateHandle(() => document.body);
const innerHTML = await handle.evaluate(body => body.innerHTML);
console.log(innerHTML);
// Get all enumerable properties of an object
const listHandle = await page.evaluateHandle(() => document.body.children);
const properties = await listHandle.getProperties();
const children = [];
for (const property of properties.values()) {
const element = property.asElement();
if (element) {
children.push(element);
}
}
// children holds elementHandles to all children of document.body
// Fetch a single property and read its JSON value
const mapHandle = await page.evaluateHandle(() => new Map([['key', 'value']]));
const sizeHandle = await mapHandle.getProperty('size');
const size = await sizeHandle.jsonValue();
console.log(size); // 1
await mapHandle.dispose();