Migrate from Stagehand
in under 10 minutes.
The API is intentionally similar. Most migrations are a find-and-replace away — and you immediately gain a 40× cost reduction and features Stagehand doesn't have.
API quick-reference
| Stagehand | Sentinel |
|---|---|
| new Stagehand({ env: 'LOCAL' }) | new Sentinel({ apiKey }) |
| stagehand.init() | sentinel.init() |
| stagehand.act({ action: '...' }) | sentinel.act('...') |
| stagehand.extract({ instruction, schema }) | sentinel.extract(instruction, schema) |
| stagehand.observe({ instruction }) | sentinel.observe(instruction) |
| stagehand.page | sentinel.page |
| stagehand.close() | sentinel.close() |
| — (manual loop) | sentinel.run(goal) |
| — (not available) | Sentinel.parallel(tasks, options) |
| — (not available) | sentinel.extend(page) |
Step-by-step migration
Five steps, most under 30 seconds each.
Replace the package
Uninstall Stagehand, install Sentinel and the Playwright browser binary.
npm install @browserbasehq/stagehandnpm install @isoldex/sentinel playwright
npx playwright install chromiumUpdate the import
Replace the Stagehand import with Sentinel. Pass your Gemini API key — free tier covers thousands of runs.
import { Stagehand } from '@browserbasehq/stagehand';
const stagehand = new Stagehand({ env: 'LOCAL' });
await stagehand.init();
const { page } = stagehand;import { Sentinel } from '@isoldex/sentinel';
const sentinel = new Sentinel({ apiKey: process.env.GEMINI_API_KEY });
await sentinel.init();Simplify act() calls
Remove the object wrapper. Sentinel's act() takes a plain string — shorter and easier to read.
await stagehand.act({ action: 'Click the login button' });
await stagehand.act({ action: 'Fill "user@example.com" into the email field' });await sentinel.act('Click the login button');
await sentinel.act('Fill "user@example.com" into the email field');Update extract()
Move the instruction to the first argument. The Zod schema stays the same — no changes needed there.
import { z } from 'zod';
const result = await stagehand.extract({
instruction: 'Get all product names and prices',
schema: z.object({
products: z.array(z.object({
name: z.string(),
price: z.number(),
}))
}),
});import { Sentinel, z } from '@isoldex/sentinel';
const result = await sentinel.extract(
'Get all product names and prices',
z.object({
products: z.array(z.object({
name: z.string(),
price: z.number(),
}))
})
);const elements = await stagehand.observe({
instruction: 'Find all login-related elements',
});const elements = await sentinel.observe('Find all login-related elements');Replace the agent loop (optional)
If you wrote a manual loop over act() + extract() calls, replace it with sentinel.run(goal). Sentinel handles planning, retries, and reflection automatically.
// Stagehand has no built-in agent loop — you write the loop manually:
await stagehand.act({ action: 'Search for laptop' });
await stagehand.act({ action: 'Click the first result' });
const data = await stagehand.extract({ instruction: '...', schema });// Sentinel runs autonomously until the goal is achieved:
const result = await sentinel.run(
'Go to Amazon, search for laptop, extract the top 5 results'
);
console.log(result.data); // extracted products
console.log(result.selectors); // stable CSS selectors for Playwright tests
console.log(result.totalSteps); // how many steps it tookawait stagehand.close();await sentinel.close();Full example
Amazon product search — before and after.
import { Stagehand } from '@browserbasehq/stagehand';
import { z } from 'zod';
const stagehand = new Stagehand({ env: 'LOCAL' });
await stagehand.init();
const { page } = stagehand;
await page.goto('https://amazon.de');
await stagehand.act({ action: 'Search for laptop' });
const data = await stagehand.extract({
instruction: 'Get the top 3 products with name and price',
schema: z.object({
products: z.array(z.object({
name: z.string(),
price: z.string(),
}))
}),
});
console.log(data.products);
await stagehand.close();import { Sentinel, z } from '@isoldex/sentinel';
const sentinel = new Sentinel({ apiKey: process.env.GEMINI_API_KEY });
await sentinel.init();
await sentinel.goto('https://amazon.de');
const result = await sentinel.run(
'Search for laptop, extract the top 3 results with name and price'
);
console.log(result.data.products);
await sentinel.close();What you gain for free
Everything below works out of the box — no extra config.
40× cheaper
Gemini Flash at $0.002/run vs. GPT-4o at $0.08/run. Same task, 40× less cost.
Self-healing locators
Successful selectors are cached and reused. LLM only called when an element breaks.
Built-in agent loop
sentinel.run(goal) plans, executes, verifies, and reflects — no manual loop required.
Parallel execution
Sentinel.parallel() runs N tasks concurrently. Stagehand has no equivalent.
OpenTelemetry
Every call emits traces and metrics. Drop into Datadog, Grafana, or Jaeger.
Any LLM
Gemini, OpenAI, Claude, Ollama — swap with one line. Stagehand is OpenAI-only.
MCP Server
Use Sentinel directly inside Cursor, Windsurf, or Claude Desktop. No code needed.
Playwright Test fixture
import { test } from '@isoldex/sentinel/test' — drop-in ai fixture for existing suites.
Ready to migrate?
Install takes 30 seconds. The free Gemini tier covers thousands of runs.