Skip to content

Node.js quickstart

  1. Install

    Terminal window
    npm install rayobrowse playwright

    Node.js 18 or newer. The samples are ES modules with top-level await: save them as .mjs files, or add "type": "module" to your package.json.

  2. Launch a browser

    // Save as quickstart.mjs and run: node quickstart.mjs
    import { Rayobrowse } from 'rayobrowse';
    import { chromium } from 'playwright';
    const PROXY = 'http://USERNAME:PASSWORD@us-east.gw.rayobyte.com:8000';
    const client = new Rayobrowse({ apiKey: 'rb_live_YOUR_KEY' });
    const wsUrl = await client.connectUrl({ os: 'windows', proxy: PROXY });
    try {
    const browser = await chromium.connectOverCDP(wsUrl);
    const context = browser.contexts()[0];
    const page = context.pages()[0] ?? (await context.newPage());
    await page.goto('https://quotes.toscrape.com/');
    console.log(await page.title()); // Quotes to Scrape
    await browser.close();
    } finally {
    await client.close();
    }

    The client calls https://browser.rayobyte.com on its own. proxy has no default, so leaving it out throws BrowserCreateError with statusCode 400 and a plain-text body that starts A proxy is required for this account.

    client.close() in finally ends the session even when the page load throws. Playwright’s browser.close() only detaches from a browser it did not launch.

  3. Watch it run

    Add vnc: true to the same call and read the live-view URL off the client:

    const liveUrl = await client.connectUrl({ os: 'windows', proxy: PROXY, vnc: true });
    console.log(client.vncUrl);
  4. Handle the limits

    import { AuthError, ConcurrencyLimitError, RateLimitError } from 'rayobrowse';
    try {
    const wsUrl = await client.connectUrl({ os: 'windows', proxy: PROXY });
    } catch (err) {
    if (err instanceof AuthError) {
    console.error('Key rejected');
    } else if (err instanceof ConcurrencyLimitError) {
    console.error(`${err.active}/${err.limit} browsers running`);
    await new Promise((r) => setTimeout(r, err.retryAfter * 1000)); // 5 s
    } else if (err instanceof RateLimitError) {
    await new Promise((r) => setTimeout(r, err.retryAfter * 1000)); // 60 s
    } else {
    throw err;
    }
    }

    Both limit errors are a 429, and they mean different things. ConcurrencyLimitError is all your browsers already running, and it carries limit and active. RateLimitError is more than 60 launches in the last minute. retryAfter comes from the retry-after header and is always a whole number of seconds, never negative.

    client.getSessionCount() answers the same question before you launch:

    console.log(await client.getSessionCount()); // { limit: 5, remaining: 5, active: 0 }

await client.close() closes the most recent session, or the id you pass it. Skip it and the browser runs until maxLifetime, 7,200 seconds by default, and all of it counts against your browser hours.

Next: Node.js reference and Limits.

Was this page helpful?