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
| Option | Type | Default | Description |
|---|
verbose | boolean | false | Enable verbose logging |
showChrome | boolean | false | Show browser window for debugging |
browserPool | BrowserPoolConfig | undefined | Browser pool configuration |
proxies | ProxyConfig[] | undefined | Array of proxies for rotation |
proxyRotation | "round-robin" | "random" | "round-robin" | Proxy rotation strategy |
skipTLSVerification | boolean | true | Skip TLS certificate verification |
BrowserPoolConfig
| Option | Type | Default | Description |
|---|
size | number | 2 | Number of browser instances |
retireAfterPages | number | 100 | Recycle browser after N pages |
retireAfterMinutes | number | 30 | Recycle browser after N minutes |
maxQueueSize | number | 100 | Max 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.
if (reader.isReady()) {
console.log("Reader is ready");
}
close()
Close the client and release resources.
async close(): Promise<void>
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
- Construction - Client is created but browser pool is not yet initialized
- First Request - Browser pool is automatically initialized on first
scrape() or crawl()
- Reuse - Subsequent requests reuse the same browser pool
- 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