Libretto vs Stagehand: compiled scripts vs runtime AI primitives.
Stagehand is a strong developer framework when you want to mix Playwright-style browser code with AI actions at runtime. Libretto is better when a known workflow should become a deterministic script your team owns, deploys, and runs without inference on every execution.
- Use Stagehand when your TypeScript app needs runtime AI browser primitives such as act(), observe(), extract(), or agent(), especially if you are already leaning on Browserbase for hosted browser sessions.
- Use Libretto when a workflow is known and repeated enough that you want code generation, direct API-call shortcuts, deterministic runs, and no model call on every execution.
- The honest distinction: Stagehand helps you decide when to use AI inside the automation. Libretto helps you stop using AI at runtime once the workflow is understood.
Stagehand mixes code with AI browser primitives
Stagehand, from Browserbase, describes itself as an AI browser automation framework. Its core idea is practical: write deterministic browser code when you know what should happen, and use natural-language AI primitives when you want the system to interpret the page.
The important primitives are act(), observe(), extract(), and agent(). observe() can return candidate actions, act() can execute a natural-language instruction or a previously observed action, extract() can pull structured data with a schema, and agent() can handle multi-step tasks. That makes Stagehand much more developer-controlled than a fully autonomous browser agent.
Stagehand also has a credible caching story. Repeatable actions can be cached and replayed to save time and tokens, while self-healing can bring AI back in when the site changes. That is useful, but it is still a runtime framework: fresh natural-language actions, extraction, and agent execution involve model inference while the automation runs.
Libretto records the workflow, then compiles it to owned code
Libretto starts from a different assumption. A coding agent uses the CLI with a live browser to inspect pages, record actions, capture relevant network calls, and compile a known workflow into a deterministic script. The result is not a prompt plus runtime AI primitive; it is code.
That script can combine Playwright with direct in-session API calls, which matters when a portal performs a slow UI sequence that maps to a cleaner underlying request. Once generated, the workflow is readable and reviewable by engineers. You debug the script, not a model's evolving interpretation of the page.
What the difference looks like in code
The comparison is easier to see in code. In Stagehand, the durable program can still contain runtime natural-language instructions. In Libretto, the goal is for the coding agent to replace the discovered workflow with explicit TypeScript before production runs.
import { Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";
const stagehand = new Stagehand({ env: "BROWSERBASE" });
await stagehand.init();
const page = stagehand.context.pages()[0];
await page.goto("https://portal.example.com");
await stagehand.act("open the latest authorization request");
const result = await stagehand.extract(
"extract the member name and current status",
z.object({
memberName: z.string(),
status: z.string(),
}),
);import { workflow } from "libretto";
import { z } from "zod";
export default workflow("readAuthorizationStatus", {
input: z.object({ authorizationId: z.string() }),
output: z.object({ memberName: z.string(), status: z.string() }),
async handler({ page }, input) {
await page.goto("https://portal.example.com/authorizations");
const response = await page.request.post(
"https://portal.example.com/api/authorizations/detail",
{ data: { id: input.authorizationId } },
);
const authorization = await response.json();
return {
memberName: authorization.member.name,
status: authorization.status,
};
},
});Comparison table
| Dimension | Stagehand | Libretto |
|---|---|---|
| Core model | ✓ A TypeScript/JavaScript framework for mixing browser code with AI primitives like act(), observe(), extract(), and agent(). | ✓ An open-source CLI for coding agents that records known workflows and turns them into deterministic automation scripts. |
| Runtime execution | — Natural-language actions and extraction generally call a model at runtime unless you are replaying cached or explicit actions. | ✓ The generated workflow runs as code; the agent helps build and maintain the script, not re-reason through every execution. |
| Artifact you own | — Your app code plus Stagehand instructions, cached actions, traces, and Browserbase session context when you use the hosted path. | ✓ A plain script your team can read, inspect, debug, version, and deploy like the rest of your codebase. |
| Determinism | — Strongest when replaying explicit observed actions; less deterministic when fresh natural-language act() or agent() calls are used. | ✓ Designed around repeatable script execution once the workflow has been recorded and reviewed. |
| Caching | ✓ Action caching can save tokens and replay prior actions; self-healing may call AI again when a page changes. | ✓ Avoids the runtime cache question for known workflows by compiling the workflow into maintained code. |
| Playwright relationship | ✓ Works with Playwright-style browser control and can bridge to Playwright pages, but exposes its own AI action model. | ✓ Combines Playwright with direct in-session API calls captured from the browser workflow. |
| Direct API-call shortcuts | — Best known for browser actions, extraction, and agent primitives; direct API-call shortcutting is not the central abstraction. | ✓ Can replace slow UI steps with direct in-session API calls when the workflow exposes cleaner network requests. |
| Cloud story | ✓ Local mode exists, but Browserbase is the first-class cloud path and the natural production on-ramp. | ✓ Generated scripts are plain code you can run in your own infrastructure, Libretto Cloud, or supported browser providers. |
| Best fit | ✓ Apps that want runtime AI flexibility inside a TypeScript browser automation framework, especially on Browserbase. | ✓ Known, repeated workflows that need to become fast, deterministic scripts with no inference on every run. |
When to use Stagehand instead
Stagehand is a good fit when you want runtime AI to stay in the loop. If your product needs to interpret pages dynamically, extract structured data from changing layouts, or execute natural-language instructions inside a TypeScript application, Stagehand gives you useful primitives without forcing you into a fully autonomous agent model.
It is also compelling if Browserbase is already your preferred browser infrastructure. Stagehand's local mode exists, but its hosted-browser story is naturally aligned with Browserbase sessions, debug URLs, regions, proxies, and related cloud features.
The fairest version of the comparison is this: Stagehand is not just another unpredictable agent. Its observe-to-act and caching workflow gives developers more control than a pure runtime agent. If you still want runtime AI adaptation, that is a real advantage.
When Libretto is the better choice
Libretto is the better choice when the workflow is known, repeated, and production-facing. At that point, runtime flexibility is often less valuable than a script that behaves the same way on the thousandth run as it did on the tenth.
That is especially true for messy portals. Libretto has been battle-tested on complex healthcare and legacy sites where small UI details, hidden API calls, and fragile state make runtime interpretation expensive to debug. The goal is to turn the portal workflow into maintainable automation code, not keep asking a model what to do next.
If your team cares about auditability, code review, reproducibility, and keeping model calls out of the hot path, Libretto's compile-to-script model is the sharper fit.
Short FAQ
+Is Stagehand open source?
Yes. Stagehand is open source and MIT-licensed in the Browserbase GitHub repository. Libretto is also open source.
+Does Stagehand run without LLM inference?
Sometimes. Stagehand can replay cached or explicit observed actions, which can avoid model calls for those steps. But natural-language act(), observe(), extract(), and agent() workflows are runtime AI primitives, and self-healing can involve AI again when the page changes.
+Is Libretto just a Stagehand alternative without Browserbase?
No. The bigger difference is the artifact. Stagehand gives you a framework for mixing code and AI primitives at runtime. Libretto uses a coding agent to turn a known workflow into a deterministic script your team owns. Libretto can still run against hosted browser providers when that is the right infrastructure choice.
+Can I use both?
Yes. Stagehand can be useful while exploring dynamic flows or building TypeScript apps that need runtime AI actions. Libretto is a better fit when a workflow has graduated from exploration into code you want to run repeatedly.
+Which one is better for legacy portals?
It depends on whether the workflow is known. Stagehand is useful when runtime adaptation is valuable. Libretto is built for repeated portal workflows where teams want deterministic scripts, inspectable code, and fewer model-dependent decisions in production.
Turn one known browser flow into owned code.
If you already know the workflow, record it with Libretto and inspect the generated script before putting it in a production path.