Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/l-xiaoshen/handstage/llms.txt

Use this file to discover all available pages before exploring further.

Handstage is distributed as scoped npm packages. Most projects need only @handstage/core. Install it with your preferred package manager and you’re ready to start automating.

Install the package

npm install @handstage/core

Packages

Handstage ships as three packages. You only install the ones you need.
PackagePurposeInstall?
@handstage/coreBrowser automation — launch Chrome, navigate pages, interact with elementsYes, for all projects
@handstage/agentAI tool definitions for passing browser control to an LLMOnly if using AI agents
@handstage/domInternal DOM utilities used by @handstage/coreNo — installed automatically as a dependency
To add @handstage/agent:
npm install @handstage/agent

TypeScript configuration

@handstage/core is published as an ES module ("type": "module"). Your project must be configured to use ES modules as well. Set "type": "module" in your package.json:
{
  "type": "module"
}
And configure your tsconfig.json to target a module format compatible with Node.js ES modules:
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true
  }
}
If your project already uses CommonJS ("type": "commonjs"), you’ll need to either migrate to ES modules or use a build tool like esbuild or tsx that handles the interop for you.

Chrome requirement

Handstage controls Chrome over the Chrome DevTools Protocol and requires Chrome or Chromium to be installed on your system. When you call V3.connectLocal(), Handstage uses chrome-launcher to locate Chrome automatically. On most systems this works out of the box:
  • macOS: Finds Chrome in /Applications/Google Chrome.app
  • Linux: Looks for google-chrome, chromium-browser, and similar executables on $PATH
  • Windows: Checks the default installation paths in Program Files
If Chrome is not in a standard location, pass the path explicitly:
import { V3 } from "@handstage/core"

const browser = await V3.connectLocal({
  localBrowserLaunchOptions: {
    executablePath: "/usr/bin/chromium-browser",
  },
})
You can also connect to a Chrome instance already running with remote debugging by providing a CDP URL:
const browser = await V3.connectLocal({
  localBrowserLaunchOptions: {
    cdpUrl: "http://localhost:9222",
  },
})

Environment variables

Handstage reads one environment variable at startup:
VariableValuesEffect
HEADLESStrueLaunches Chrome in headless mode (no visible window). Any other value or absence runs Chrome with a visible UI.
Set HEADLESS=true in your environment to run without a display, for example in CI:
HEADLESS=true node --loader ts-node/esm your-script.ts
You can also control headless mode programmatically via localBrowserLaunchOptions.headless instead of the environment variable.

Verify the installation

Create a file called verify.ts and run it to confirm everything is working:
import { V3 } from "@handstage/core"

const browser = await V3.connectLocal()
const page = await browser.context.newPage("https://example.com")
console.log("Page title:", await page.title())
await browser.close()
If you see the page title printed without errors, your setup is complete.

Next steps

Quickstart

Walk through a complete first automation script step by step.

Connecting to Chrome

Learn all the ways to launch or attach to a Chrome instance.

Build docs developers (and LLMs) love