Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.1.0"
".": "1.1.1"
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.1.1 (2025-08-20)

Full Changelog: [v1.1.0...v1.1.1](https://github.com/browser-use/browser-use-node/compare/v1.1.0...v1.1.1)

## 1.1.0 (2025-08-20)

Full Changelog: [v1.0.0...v1.1.0](https://github.com/browser-use/browser-use-node/compare/v1.0.0...v1.1.0)
Expand Down
51 changes: 20 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,28 @@
# Browser Use TypeScript API Library

[![NPM version](<https://img.shields.io/npm/v/browser-use-sdk.svg?label=npm%20(stable)>)](https://npmjs.org/package/browser-use-sdk) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/browser-use-sdk)

This library provides convenient access to the Browser Use REST API from server-side TypeScript or JavaScript.

The REST API documentation can be found on [docs.browser-use.com](https://docs.browser-use.com/cloud/). The full API of this library can be found in [api.md](api.md).

It is generated with [Stainless](https://www.stainless.com/).

## Installation
<img src="./assets/cloud-banner-js.png" alt="Browser Use JS" width="full"/>

```sh
npm install browser-use-sdk
pnpm add browser-use-sdk
```

## Usage
## QuickStart

The full API of this library can be found in [api.md](api.md).

<!-- prettier-ignore -->
```js
```ts
import BrowserUse from 'browser-use-sdk';

const client = new BrowserUse({
apiKey: process.env['BROWSER_USE_API_KEY'], // This is the default and can be omitted
});

// #1 - Run a task and get its result
const client = new BrowserUse();

const task = await client.tasks.run({
const result = await client.tasks.run({
task: 'Search for the top 10 Hacker News posts and return the title and url.',
});

console.log(task.doneOutput);
console.log(result.doneOutput);
```

// #2 - Run a task with a structured result
> The full API of this library can be found in [api.md](api.md).

### Structured Output with Zod

```ts
import z from 'zod';

const TaskOutput = z.object({
Expand All @@ -47,23 +34,25 @@ const TaskOutput = z.object({
),
});

const posts = await client.tasks.run({
const result = await client.tasks.run({
task: 'Search for the top 10 Hacker News posts and return the title and url.',
});

for (const post of posts.doneOutput.posts) {
for (const post of result.parsedOutput.posts) {
console.log(`${post.title} - ${post.url}`);
}
```

// #3 - Stream Task Progress
### Streaming Agent Updates

const hn = await browseruse.tasks.create({
```ts
const task = await browseruse.tasks.create({
task: 'Search for the top 10 Hacker News posts and return the title and url.',
schema: TaskOutput,
});

const stream = browseruse.tasks.stream({
taskId: hn.id,
taskId: task.id,
schema: TaskOutput,
});

Expand All @@ -78,7 +67,7 @@ for await (const msg of stream) {
case 'finished':
console.log(`done:`);

for (const post of msg.doneOutput.posts) {
for (const post of msg.parsedOutput.posts) {
console.log(`${post.title} - ${post.url}`);
}
break;
Expand Down
Binary file added assets/cloud-banner-js.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 0 additions & 43 deletions examples/demo.ts

This file was deleted.

55 changes: 42 additions & 13 deletions examples/zod.ts → examples/retrieve.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,47 @@
#!/usr/bin/env -S npm run tsn -T

import { BrowserUse } from 'browser-use-sdk';
import { z } from 'zod';

import { env, spinner } from './utils';
import z from 'zod';

env();

// gets API Key from environment variable BROWSER_USE_API_KEY
const browseruse = new BrowserUse();

async function basic() {
let log = 'starting';
const stop = spinner(() => log);

// Create Task
const rsp = await browseruse.tasks.create({
task: "What's the weather line in SF and what's the temperature?",
agentSettings: { llm: 'gemini-2.5-flash' },
});

poll: do {
// Wait for Task to Finish
const status = await browseruse.tasks.retrieve(rsp.id);

switch (status.status) {
case 'started':
case 'paused':
case 'stopped':
log = `agent ${status.status} - live: ${status.session.liveUrl}`;

await new Promise((resolve) => setTimeout(resolve, 2000));
break;

case 'finished':
stop();

console.log(status.doneOutput);
break poll;
}
} while (true);
}

// Define Structured Output Schema
const HackerNewsResponse = z.object({
title: z.string(),
Expand All @@ -21,14 +53,15 @@ const TaskOutput = z.object({
posts: z.array(HackerNewsResponse),
});

async function main() {
async function structured() {
let log = 'starting';
const stop = spinner(() => log);

// Create Task
const rsp = await browseruse.tasks.create({
task: 'Extract top 10 Hacker News posts and return the title, url, and score',
schema: TaskOutput,
agentSettings: { llm: 'gpt-4.1' },
});

poll: do {
Expand All @@ -42,30 +75,24 @@ async function main() {
case 'started':
case 'paused':
case 'stopped': {
const stepsCount = status.steps ? status.steps.length : 0;
const steps = `${stepsCount} steps`;
const lastGoalDescription = stepsCount > 0 ? status.steps![stepsCount - 1]!.nextGoal : undefined;
const lastGoal = lastGoalDescription ? `, last: ${lastGoalDescription}` : '';
const liveUrl = status.session.liveUrl ? `, live: ${status.session.liveUrl}` : '';

log = `agent ${status.status} (${steps}${lastGoal}${liveUrl}) `;
log = `agent ${status.status} ${status.session.liveUrl} | ${status.steps.length} steps`;

await new Promise((resolve) => setTimeout(resolve, 2000));

break;
}

case 'finished':
if (status.doneOutput == null) {
if (status.parsedOutput == null) {
throw new Error('No output');
}

stop();

// Print Structured Output
console.log('TOP POSTS:');
console.log('Top Hacker News Posts:');

for (const post of status.doneOutput.posts) {
for (const post of status.parsedOutput.posts) {
console.log(` - ${post.title} (${post.score}) ${post.url}`);
}

Expand All @@ -74,4 +101,6 @@ async function main() {
} while (true);
}

main().catch(console.error);
basic()
.then(() => structured())
.catch(console.error);
45 changes: 0 additions & 45 deletions examples/run-zod.ts

This file was deleted.

48 changes: 44 additions & 4 deletions examples/run.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env -S npm run tsn -T

import { BrowserUse } from 'browser-use-sdk';
import { z } from 'zod';

import { env } from './utils';

Expand All @@ -9,15 +10,54 @@ env();
// gets API Key from environment variable BROWSER_USE_API_KEY
const browseruse = new BrowserUse();

async function main() {
console.log(`Running Task...`);
async function basic() {
console.log(`Basic: Running Task...`);

// Create Task
const rsp = await browseruse.tasks.run({
task: "What's the weather line in SF and what's the temperature?",
agentSettings: { llm: 'gemini-2.5-flash' },
});

console.log(rsp.doneOutput);
console.log(`Basic: ${rsp.doneOutput}`);

console.log(`Basic: DONE`);
}

const HackerNewsResponse = z.object({
title: z.string(),
url: z.string(),
});

const TaskOutput = z.object({
posts: z.array(HackerNewsResponse),
});

async function structured() {
console.log(`Structured: Running Task...`);

// Create Task
const rsp = await browseruse.tasks.run({
task: 'Search for the top 10 Hacker News posts and return the title and url!',
schema: TaskOutput,
agentSettings: { llm: 'gpt-4.1' },
});

const posts = rsp.parsedOutput?.posts;

if (posts == null) {
throw new Error('Structured: No posts found');
}

console.log(`Structured: Top Hacker News posts:`);

for (const post of posts) {
console.log(` - ${post.title} - ${post.url}`);
}

console.log(`\nStructured: DONE`);
}

main().catch(console.error);
basic()
.then(() => structured())
.catch(console.error);
Loading