npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@olib-ai/owl-browser-sdk

v2.0.7

Published

Node.js SDK for Owl Browser automation - Async-first with dynamic OpenAPI method generation

Downloads

700

Readme

@olib-ai/owl-browser-sdk

Node.js SDK v2 for Owl Browser - AI-native browser automation with antidetect capabilities.

Features

  • Async-first design - All operations are async/await based
  • Dynamic method generation - 144+ browser tools available as typed methods
  • OpenAPI schema bundled - Works offline, no need to fetch schema from server
  • Flow execution engine - Run complex automation flows with conditions and expectations
  • JWT and Token auth - Flexible authentication options
  • TypeScript support - Full type definitions included
  • Retry with backoff - Built-in retry logic with exponential backoff and jitter

Installation

npm install @olib-ai/owl-browser-sdk

Quick Start

import { OwlBrowser, RemoteConfig } from '@olib-ai/owl-browser-sdk';

const browser = new OwlBrowser({
  url: 'http://localhost:8080',
  token: 'your-secret-token',
  apiPrefix: ''  // Use '' for direct connection, '/api' for nginx proxy
});

await browser.connect();

// Create a context
const ctx = await browser.createContext();
const contextId = ctx.context_id;

// Navigate to a page
await browser.navigate({ context_id: contextId, url: 'https://example.com' });

// Click an element
await browser.click({ context_id: contextId, selector: 'button#submit' });

// Take a screenshot
const screenshot = await browser.screenshot({ context_id: contextId });

// Close the context
await browser.closeContext({ context_id: contextId });

await browser.close();

Configuration

RemoteConfig Options

interface RemoteConfig {
  // Required
  url: string;                    // Server URL (e.g., 'http://localhost:8080')
  
  // Authentication (one required)
  token?: string;                 // Bearer token for TOKEN auth
  authMode?: AuthMode;            // 'token' (default) or 'jwt'
  jwt?: JWTConfig;                // JWT configuration for JWT auth
  
  // Optional
  transport?: TransportMode;      // 'http' (default) or 'websocket'
  timeout?: number;               // Request timeout in seconds (default: 30)
  maxConcurrent?: number;         // Max concurrent requests (default: 10)
  retry?: RetryConfig;            // Retry configuration
  verifySsl?: boolean;            // Verify SSL certificates (default: true)
  apiPrefix?: string;             // API prefix (default: '/api', use '' for direct)
}

JWT Authentication

import { OwlBrowser, AuthMode } from '@olib-ai/owl-browser-sdk';

const browser = new OwlBrowser({
  url: 'http://localhost:8080',
  authMode: AuthMode.JWT,
  jwt: {
    privateKeyPath: '/path/to/private.pem',
    expiresIn: 3600,        // Token validity in seconds
    refreshThreshold: 300,   // Refresh when < 300s remaining
    issuer: 'my-app',
    claims: { custom: 'data' }
  }
});

Dynamic Methods

The SDK dynamically generates methods for all 144+ browser tools. Methods are available in both camelCase and snake_case:

// These are equivalent
await browser.createContext();
await browser.create_context();

// Navigation
await browser.navigate({ context_id: ctx, url: 'https://example.com' });
await browser.reload({ context_id: ctx });
await browser.goBack({ context_id: ctx });
await browser.goForward({ context_id: ctx });

// Interaction
await browser.click({ context_id: ctx, selector: '#button' });
await browser.type({ context_id: ctx, selector: '#input', text: 'Hello' });
await browser.scroll({ context_id: ctx, direction: 'down' });

// Data extraction
await browser.getHtml({ context_id: ctx });
await browser.getMarkdown({ context_id: ctx });
await browser.screenshot({ context_id: ctx });

// AI-powered tools
await browser.queryPage({ context_id: ctx, question: 'What is the title?' });
await browser.solveCaptcha({ context_id: ctx });
await browser.findElement({ context_id: ctx, description: 'login button' });

Flow Execution

Execute complex automation flows with variable resolution and expectations:

import { OwlBrowser, FlowExecutor } from '@olib-ai/owl-browser-sdk';

const browser = new OwlBrowser({ url: '...', token: '...' });
await browser.connect();

const ctx = await browser.createContext();
const executor = new FlowExecutor(browser, ctx.context_id);

// Load flow from JSON file
const flow = FlowExecutor.loadFlow('test-flows/navigation.json');
const result = await executor.execute(flow);

if (result.success) {
  console.log('Flow completed in', result.totalDurationMs, 'ms');
} else {
  console.error('Flow failed:', result.error);
}

Flow JSON Format

{
  "name": "Login Flow",
  "description": "Automates login process",
  "steps": [
    {
      "type": "browser_navigate",
      "url": "https://example.com/login"
    },
    {
      "type": "browser_type",
      "selector": "#email",
      "text": "[email protected]"
    },
    {
      "type": "browser_type",
      "selector": "#password",
      "text": "secret123"
    },
    {
      "type": "browser_click",
      "selector": "#submit",
      "expected": {
        "notEmpty": true
      }
    },
    {
      "type": "browser_wait_for_selector",
      "selector": ".dashboard",
      "expected": {
        "equals": true,
        "field": "found"
      }
    }
  ]
}

Variable Resolution

Use ${prev} to reference previous step results:

{
  "steps": [
    {
      "type": "browser_evaluate",
      "script": "document.querySelector('.user-id').textContent"
    },
    {
      "type": "browser_navigate",
      "url": "https://example.com/users/${prev}"
    }
  ]
}

Supported syntax:

  • ${prev} - Entire previous result
  • ${prev.field} - Field in previous result
  • ${prev[0]} - Array element
  • ${prev[0].id} - Nested access

Expectations

Validate step results:

const expectation = {
  equals: 'expected value',     // Exact match
  contains: 'substring',        // String contains
  length: 5,                    // Array/string length
  greaterThan: 10,              // Numeric comparison
  lessThan: 100,                // Numeric comparison
  notEmpty: true,               // Not null/empty
  matches: '^[A-Z]+$',          // Regex pattern
  field: 'data.items'           // Nested field to check
};

Conditional Branching

{
  "type": "condition",
  "condition": {
    "source": "previous",
    "operator": "equals",
    "field": "success",
    "value": true
  },
  "onTrue": [
    { "type": "browser_click", "selector": "#continue" }
  ],
  "onFalse": [
    { "type": "browser_screenshot" }
  ]
}

Playwright-Compatible API

Drop-in Playwright API that translates Playwright calls to Owl Browser tools. Use your existing Playwright code with Owl Browser's antidetect capabilities.

import { chromium, devices } from '@olib-ai/owl-browser-sdk/playwright';

const browser = await chromium.connect('http://localhost:8080', { token: 'your-token' });
const context = await browser.newContext(devices['iPhone 15 Pro']);
const page = await context.newPage();

await page.goto('https://example.com');
await page.click('button#submit');
await page.fill('#search', 'query');

const text = await page.textContent('h1');
const screenshot = await page.screenshot({ path: 'page.png' });

// Locators
const button = page.locator('button.primary');
await button.click();

// Playwright-style selectors
const login = page.getByRole('button', { name: 'Log in' });
const input = page.getByPlaceholder('Enter email');
const heading = page.getByText('Welcome');

await context.close();
await browser.close();

Supported features: Page navigation, click/fill/type/press, locators (CSS, text, role, test-id, xpath), frames, keyboard & mouse input, screenshots, network interception (route/unroute), dialogs, downloads, viewport emulation, and 20+ device descriptors (iPhone, Pixel, Galaxy, iPad, Desktop).

Data Extraction

Universal structured data extraction from any website — CSS selectors, auto-detection, tables, metadata, and multi-page scraping with pagination. No AI dependencies, works deterministically with cheerio.

import { OwlBrowser } from '@olib-ai/owl-browser-sdk';
import { Extractor } from '@olib-ai/owl-browser-sdk/extraction';

const browser = new OwlBrowser({ url: '...', token: '...' });
await browser.connect();
const ctx = await browser.createContext();

const ex = new Extractor(browser, ctx.context_id);
await ex.goto('https://example.com/products');

// CSS selector extraction
const products = await ex.select('.product-card', {
  name: 'h3',
  price: '.price',
  image: 'img@src',
  link: 'a@href',
});

// Auto-detect repeating patterns (zero-config)
const patterns = await ex.detect();

// Multi-page scraping with automatic pagination
const result = await ex.scrape('.product-card', {
  fields: { name: 'h3', price: '.price', sku: '@data-sku' },
  maxPages: 10,
  deduplicateBy: 'sku',
});
console.log(`${result.totalItems} items from ${result.pagesScraped} pages`);

Capabilities:

| Method | Description | |--------|-------------| | select() / selectFirst() | Extract with CSS selectors and field specs ("selector", "selector@attr", object specs with transforms) | | table() / grid() / definitionList() | Parse <table>, CSS grid/flexbox, and <dl> structures | | meta() / jsonLd() | Extract OpenGraph, Twitter Card, JSON-LD, microdata, feeds | | detect() / detectAndExtract() | Auto-discover repeating DOM patterns | | lists() | Extract list/card containers with auto-field inference | | scrape() | Multi-page with pagination detection (click-next, URL patterns, buttons, load-more, infinite scroll) | | clean() | Remove cookie banners, modals, fixed elements, ads | | html() / markdown() / text() | Raw content with cleaning levels |

All extraction functions are also available as standalone pure functions for use without a browser connection.

Error Handling

import {
  OwlBrowserError,
  ConnectionError,
  AuthenticationError,
  ToolExecutionError,
  TimeoutError,
  RateLimitError,
  ElementNotFoundError
} from '@olib-ai/owl-browser-sdk';

try {
  await browser.click({ context_id: ctx, selector: '#nonexistent' });
} catch (e) {
  if (e instanceof ElementNotFoundError) {
    console.log('Element not found:', e.selector);
  } else if (e instanceof TimeoutError) {
    console.log('Operation timed out after', e.timeoutMs, 'ms');
  } else if (e instanceof RateLimitError) {
    console.log('Rate limited. Retry after', e.retryAfter, 'seconds');
  } else if (e instanceof AuthenticationError) {
    console.log('Auth failed:', e.message);
  }
}

Advanced Usage

Direct Transport Access

import { HTTPTransport, WebSocketTransport } from '@olib-ai/owl-browser-sdk';

// Use HTTP transport directly
const transport = new HTTPTransport({
  url: 'http://localhost:8080',
  token: 'secret'
});

await transport.connect();
const result = await transport.execute('browser_navigate', {
  context_id: 'ctx_1',
  url: 'https://example.com'
});
await transport.close();

OpenAPI Schema Access

import { OpenAPILoader, getBundledSchema } from '@olib-ai/owl-browser-sdk';

// Get bundled schema
const schema = getBundledSchema();
console.log('API Version:', schema.info.version);

// Load and parse schema
const loader = new OpenAPILoader(schema);
for (const [name, tool] of loader.tools) {
  console.log(name + ':', tool.description);
}

API Reference

OwlBrowser

  • connect(): Promise<void> - Connect to server
  • close(): Promise<void> - Close connection
  • execute(toolName, params): Promise<unknown> - Execute any tool
  • healthCheck(): Promise<HealthResponse> - Check server health
  • listTools(): string[] - List all tool names
  • listMethods(): string[] - List all method names
  • getTool(name): ToolDefinition | undefined - Get tool definition

FlowExecutor

  • execute(flow): Promise<FlowResult> - Execute a flow
  • abort(): void - Abort current execution
  • reset(): void - Reset abort flag
  • static loadFlow(path): Flow - Load flow from JSON file
  • static parseFlow(data): Flow - Parse flow from object

Extractor

  • goto(url, options?): Promise<void> - Navigate to URL
  • select(selector, fields): Promise<Record[]> - Extract from all matches
  • selectFirst(selector, fields): Promise<Record | null> - Extract first match
  • count(selector): Promise<number> - Count matching elements
  • table(selector?, options?): Promise<Record[]> - Parse HTML tables
  • grid(container, item?): Promise<Record[]> - Parse CSS grids
  • definitionList(selector?): Promise<Record> - Parse <dl> lists
  • detectTables(): Promise<TableInfo[]> - Auto-detect tables
  • meta(): Promise<MetaData> - Extract page metadata
  • jsonLd(): Promise<object[]> - Extract JSON-LD
  • detect(options?): Promise<DetectedPattern[]> - Detect repeating patterns
  • detectAndExtract(options?): Promise<Record[]> - Detect + extract
  • lists(selector, options?): Promise<Record[]> - Extract lists/cards
  • scrape(selector, options?): Promise<ExtractionResult> - Multi-page scrape
  • abortScrape(): void - Abort running scrape
  • clean(options?): Promise<CleanResult> - Remove obstructions
  • html(options?): Promise<string> - Get page HTML
  • markdown(): Promise<string> - Get page markdown
  • text(selector?, regex?): Promise<string> - Get filtered text
  • detectSite(): Promise<string> - Detect site type
  • siteData(template?): Promise<unknown> - Site-specific extraction

Requirements

  • Node.js 18+
  • TypeScript 5+ (optional, for type definitions)

License

MIT - See LICENSE file for details.

Links

  • Website: https://www.owlbrowser.net
  • Documentation: https://www.owlbrowser.net/docs
  • GitHub: https://github.com/Olib-AI/olib-browser
  • Support: [email protected]