Skip to main content
ReaderClient is the recommended way to use Reader. It manages the browser lifecycle automatically and provides a simple interface for scraping and crawling.

Import

import { ReaderClient } from "@vakra-dev/reader";

Constructor

const reader = new ReaderClient(options?: ReaderClientOptions);

ReaderClientOptions

OptionTypeDefaultDescription
verbosebooleanfalseEnable verbose logging
showChromebooleanfalseShow browser window for debugging
browserPoolBrowserPoolConfigundefinedBrowser pool configuration
proxiesProxyConfig[]undefinedArray of proxies for rotation
proxyRotation"round-robin" | "random""round-robin"Proxy rotation strategy
skipTLSVerificationbooleantrueSkip TLS certificate verification

BrowserPoolConfig

OptionTypeDefaultDescription
sizenumber2Number of browser instances
retireAfterPagesnumber100Recycle browser after N pages
retireAfterMinutesnumber30Recycle browser after N minutes
maxQueueSizenumber100Max pending requests in queue

Methods

scrape()

Scrape one or more URLs.
async scrape(options: ScrapeOptions): Promise<ScrapeResult>
const result = await reader.scrape({
  urls: ["https://example.com"],
  formats: ["markdown", "html"],
});
Full ScrapeOptions reference →

crawl()

Crawl a website to discover pages.
async crawl(options: CrawlOptions): Promise<CrawlResult>
const result = await reader.crawl({
  url: "https://example.com",
  depth: 2,
  maxPages: 50,
  scrape: true,
});
Full CrawlOptions reference →

start()

Pre-initialize the browser pool. Called automatically on first scrape/crawl.
async start(): Promise<void>
// Warm up the browser pool before handling requests
await reader.start();

isReady()

Check if the client is initialized and ready.
isReady(): boolean
if (reader.isReady()) {
  console.log("Reader is ready");
}

close()

Close the client and release resources.
async close(): Promise<void>
await reader.close();
close() is optional - the client auto-closes on process exit.

Examples

Basic Usage

import { ReaderClient } from "@vakra-dev/reader";

const reader = new ReaderClient();

const result = await reader.scrape({
  urls: ["https://example.com"],
});

console.log(result.data[0].markdown);

await reader.close();

With Browser Pool Configuration

const reader = new ReaderClient({
  browserPool: {
    size: 5,
    retireAfterPages: 50,
    retireAfterMinutes: 15,
  },
  verbose: true,
});

With Proxy Rotation

const reader = new ReaderClient({
  proxies: [
    { host: "proxy1.example.com", port: 8080, username: "user", password: "pass" },
    { host: "proxy2.example.com", port: 8080, username: "user", password: "pass" },
  ],
  proxyRotation: "round-robin",
});

Server Usage

import { ReaderClient } from "@vakra-dev/reader";
import express from "express";

// Create once at startup
const reader = new ReaderClient({
  browserPool: { size: 5 },
});

const app = express();

app.post("/scrape", async (req, res) => {
  const result = await reader.scrape({ urls: req.body.urls });
  res.json(result);
});

// Graceful shutdown
process.on("SIGTERM", async () => {
  await reader.close();
  process.exit(0);
});

app.listen(3000);

Lifecycle

  1. Construction - Client is created but browser pool is not yet initialized
  2. First Request - Browser pool is automatically initialized on first scrape() or crawl()
  3. Reuse - Subsequent requests reuse the same browser pool
  4. Close - Call close() to release resources, or let it auto-close on process exit
new ReaderClient() → scrape()/crawl() → [pool initialized] → scrape()/crawl() → close()
                         ↑                                         ↑
                    auto-init                                  reuses pool