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

@apexcli/browser

v0.5.0

Published

Browser automation capabilities for APEX using Playwright

Readme

@apexcli/browser

Browser automation capabilities for APEX using Playwright. This package provides browser automation tools for AI agents with comprehensive lifecycle management.

Features

  • Browser Instance Management: Centralized management of browser instances with pooling and reuse
  • Context Isolation: Create isolated browser contexts for different automation tasks
  • Resource Monitoring: Track memory usage and automatically cleanup idle instances
  • Console & Error Capture: Real-time capture of browser console messages and JavaScript errors
  • Screenshot Support: Capture full-page or element-specific screenshots with format and quality control
  • Screenshot Utilities: Base utility functions for direct page/context screenshot capture
  • Element Interaction: Click, type, scroll, and interact with page elements
  • Navigation Control: Advanced navigation with wait strategies and timeout controls
  • Event Streaming: Real-time events for browser and context lifecycle

Quick Start

import { createBrowserManager, createBrowserSession } from '@apexcli/browser';

// Create a browser manager
const manager = createBrowserManager({
  maxInstances: 5,
  reuseInstances: true
});

// Create and launch a browser session
const session = createBrowserSession(manager, {
  browserType: 'chromium',
  headless: true,
  viewport: { width: 1280, height: 720 }
});

await session.launch();

// Navigate and interact with pages
await session.navigate('https://example.com');
await session.click('button#submit');
await session.type('#input', 'Hello World');

// Take screenshots
const screenshot = await session.screenshot({ fullPage: true });

// Clean up
await session.close();
await manager.shutdown();

Screenshot Utilities

For direct screenshot capture from Playwright Page or BrowserContext objects:

import { captureScreenshot, capturePNG, captureJPEG } from '@apexcli/browser';
import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

// Base screenshot utility with format and quality support
const pngResult = await captureScreenshot(page, {
  format: 'png',
  fullPage: true
});

const jpegResult = await captureScreenshot(page, {
  format: 'jpeg',
  quality: 80,
  path: './screenshot.jpg'
});

// Convenience functions
const pngScreenshot = await capturePNG(page, { fullPage: true });
const jpegScreenshot = await captureJPEG(page, 90); // 90% quality

// Works with BrowserContext too
const contextResult = await captureScreenshot(context, {
  format: 'png',
  omitBackground: true
});

if (jpegResult.success) {
  console.log(`Screenshot captured: ${jpegResult.data!.length} bytes`);
  console.log(`Capture took: ${jpegResult.duration}ms`);
}

Screenshot Utility Functions

  • captureScreenshot(target, options): Base utility accepting Page/BrowserContext

    • Format: PNG (default) or JPEG
    • Quality: 1-100 for JPEG (default 80)
    • Full page or viewport capture
    • Optional file saving
    • Returns Buffer with metadata
  • capturePNG(target, options): Convenience function for PNG screenshots

  • captureJPEG(target, quality, options): Convenience function for JPEG screenshots

  • captureFullPageScreenshot(target, options): Full scrollable page capture

  • captureViewportScreenshot(target, options): Viewport-only capture

Core Classes

BrowserManager

Manages browser instances and their lifecycle:

import { BrowserManager } from '@apexcli/browser';

const manager = new BrowserManager({
  maxInstances: 3,
  instanceIdleTimeout: 300000, // 5 minutes
  reuseInstances: true,
  resourceLimits: {
    maxMemoryMB: 1024,
    maxCpuPercent: 80
  }
});

// Launch browser instance
const result = await manager.launchBrowser({ browserType: 'chromium' });

// Create isolated contexts
const context = await manager.createContext(result.data.id);

// Monitor resource usage
const usage = await manager.getResourceUsage();
console.log(`Active instances: ${usage.totalInstances}`);

BrowserSession

High-level interface for browser automation:

import { BrowserSession } from '@apexcli/browser';

const session = new BrowserSession(manager, {
  browserType: 'firefox',
  headless: false,
  userAgent: 'Custom Agent String'
});

await session.launch();

// Page navigation
await session.navigate('https://example.com', {
  waitUntil: 'networkidle',
  timeout: 30000
});

// Element interaction
await session.click({ type: 'testId', value: 'submit-button' });
await session.waitForElement('#result', { state: 'visible' });

// JavaScript evaluation
const result = await session.evaluate(() => {
  return document.title;
});

// Console monitoring
session.on('consoleMessage', (message) => {
  console.log(`Browser: ${message.text}`);
});

Configuration Options

Browser Session Config

interface BrowserSessionConfig {
  browserType: 'chromium' | 'firefox' | 'webkit';
  headless: boolean;
  viewport?: { width: number; height: number };
  timeout?: number;
  userAgent?: string;
  ignoreHTTPSErrors?: boolean;
  launchOptions?: LaunchOptions;
  contextOptions?: BrowserContextOptions;
}

Manager Config

interface BrowserManagerConfig {
  maxInstances?: number;
  defaultSessionConfig?: Partial<BrowserSessionConfig>;
  instanceIdleTimeout?: number;
  reuseInstances?: boolean;
  resourceLimits?: {
    maxMemoryMB?: number;
    maxCpuPercent?: number;
  };
}

Capture Config

interface CaptureConfig {
  captureConsole: boolean;
  consoleLevels?: ConsoleLogLevel[];
  captureErrors: boolean;
  maxBufferSize?: number;
  includeStackTraces?: boolean;
}

Element Selectors

Support for multiple selector types:

// String selectors
await session.click('#button');
await session.click('[data-testid="submit"]');

// Typed selectors
await session.click({ type: 'css', value: '#button' });
await session.click({ type: 'xpath', value: '//button[text()="Submit"]' });
await session.click({ type: 'text', value: 'Click me' });
await session.click({ type: 'role', value: 'button' });
await session.click({ type: 'testId', value: 'submit-btn' });

Error Handling

All browser operations return a standardized result format:

interface BrowserActionResult<T> {
  success: boolean;
  data?: T;
  error?: string;
  duration: number;
}

const result = await session.navigate('https://example.com');
if (result.success) {
  console.log(`Navigated to: ${result.data}`);
} else {
  console.error(`Navigation failed: ${result.error}`);
}

Resource Management

The browser manager automatically:

  • Limits concurrent browser instances
  • Reuses instances when possible
  • Monitors memory and CPU usage
  • Cleans up idle instances
  • Provides resource usage statistics
// Get current resource usage
const usage = await manager.getResourceUsage();
console.log(`Memory: ${usage.memoryUsageMB}MB`);
console.log(`Active browsers: ${usage.activeBrowsers}`);

// Force cleanup of idle instances
const cleanedCount = await manager.cleanupIdleInstances();
console.log(`Cleaned up ${cleanedCount} idle instances`);

// Listen for resource limit events
manager.on('resourceLimitExceeded', (info) => {
  console.warn(`${info.type} limit exceeded: ${info.value}/${info.limit}`);
});

Event Monitoring

Real-time events for monitoring and debugging:

// Browser lifecycle events
manager.on('browserCreated', (info) => {
  console.log(`Browser created: ${info.id} (${info.type})`);
});

manager.on('contextCreated', (info) => {
  console.log(`Context created: ${info.id}`);
});

// Console and error capture
session.on('consoleMessage', (message) => {
  console.log(`[${message.type}] ${message.text}`);
});

session.on('javascriptError', (error) => {
  console.error(`JS Error: ${error.message}`);
});

session.on('pageError', (error) => {
  console.error(`Page Error: ${error.message}`);
});

Testing

Run the test suite:

npm test

The package includes comprehensive tests for:

  • Browser manager lifecycle
  • Session management
  • Element interaction
  • Error handling
  • Resource management
  • Integration scenarios

Dependencies

  • playwright: Browser automation library
  • eventemitter3: Event emitter for real-time events
  • @apexcli/core: Core APEX types and utilities

License

MIT - See LICENSE file for details