
Security News
GitHub Actions Adds cache-mode to Limit Cache Poisoning Risk
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.
@copperline/rendex
Advanced tools
Official TypeScript SDK for Rendex — render HTML to images, generate PDFs, and capture screenshots
Official TypeScript SDK for Rendex — the HTML-to-image, PDF, and screenshot rendering API. Turn raw HTML, Markdown, or any webpage into an image or PDF with a single function call.
fetch)npm install @copperline/rendex
# or
pnpm add @copperline/rendex
# or
bun add @copperline/rendex
import { Rendex } from "@copperline/rendex";
const rendex = new Rendex("your-api-key");
// Render raw HTML straight to a PNG
const { image, metadata } = await rendex.renderHtml("<h1>Hello, world</h1>");
// Or render Markdown (converted to HTML server-side)
const md = await rendex.renderMarkdown("# Hello, world");
// Or capture a live URL
const shot = await rendex.screenshot({
url: "https://example.com",
format: "png",
fullPage: true,
});
// Write to file (Node.js)
import { writeFile } from "node:fs/promises";
await writeFile("screenshot.png", image);
console.log(`${metadata.bytesSize} bytes, loaded in ${metadata.loadTimeMs}ms`);
new Rendex(apiKey, config?)Create a new Rendex client.
const rendex = new Rendex("your-api-key", {
baseUrl: "https://api.rendex.dev", // optional, default
});
| Parameter | Type | Description |
|---|---|---|
apiKey | string | Your Rendex API key. Get one at rendex.dev |
config.baseUrl | string | Override the API base URL |
config.fetch | typeof fetch | Custom fetch implementation (for testing) |
rendex.screenshot(options)Capture a screenshot and return the binary image with metadata.
const { image, metadata } = await rendex.screenshot({
url: "https://example.com",
format: "webp",
width: 1920,
height: 1080,
darkMode: true,
});
Returns Promise<ScreenshotResult>:
image — Uint8Array of the captured imagemetadata — ScreenshotMetadata with URL, dimensions, format, bytes, load time, quality signalrendex.renderHtml(html, options?)Render raw HTML straight to a PNG (or any format) and return the binary image with metadata. Convenience wrapper over screenshot({ html }).
const { image, metadata } = await rendex.renderHtml("<h1>Hello, world</h1>", {
format: "png",
width: 1200,
});
Returns Promise<ScreenshotResult> — same shape as screenshot().
rendex.renderHtmlJson(html, options?)Render raw HTML and return JSON with a base64-encoded image. Convenience wrapper over screenshotJson({ html }).
const result = await rendex.renderHtmlJson("<h1>Hello, world</h1>");
console.log(result.data.bytesSize);
Returns Promise<ScreenshotJsonResponse> — same shape as screenshotJson().
rendex.renderMarkdown(markdown, options?)Render Markdown straight to a PNG (or any format) and return the binary image with metadata. The Markdown is converted to HTML server-side. Convenience wrapper over screenshot({ markdown }).
const { image, metadata } = await rendex.renderMarkdown("# Hello, world", {
format: "png",
width: 1200,
});
Returns Promise<ScreenshotResult> — same shape as screenshot().
rendex.renderMarkdownJson(markdown, options?)Render Markdown and return JSON with a base64-encoded image. The Markdown is converted to HTML server-side. Convenience wrapper over screenshotJson({ markdown }).
const result = await rendex.renderMarkdownJson("# Hello, world");
console.log(result.data.bytesSize);
Returns Promise<ScreenshotJsonResponse> — same shape as screenshotJson().
HTML and Markdown rendering is POST-only and accepts up to 5MB. It is not available via
screenshotUrl()(the GET endpoint can't carry a body). Provide exactly one ofurl,html, ormarkdown.
rendex.screenshotJson(options)Capture a screenshot and return JSON with a base64-encoded image.
const result = await rendex.screenshotJson({
url: "https://example.com",
});
console.log(result.data.image); // base64 string
console.log(result.data.bytesSize); // 45823
console.log(result.meta.usage?.remaining); // 499
Returns Promise<ScreenshotJsonResponse> with data (image + metadata) and meta (request ID, usage).
rendex.screenshotUrl(options)Generate a GET URL for embedding. No network call — pure URL builder.
const url = rendex.screenshotUrl({
url: "https://example.com",
format: "png",
width: 1200,
});
// Use in <img> tags, OpenGraph, etc.
Note: The API key is included in the URL. Use server-side only.
Returns string — a complete URL to the screenshot endpoint.
All options except url are optional:
| Option | Type | Default | Description |
|---|---|---|---|
url | string | required | The webpage URL to capture |
format | "png" | "jpeg" | "webp" | "pdf" | "png" | Output format |
width | number | 1280 | Viewport width (320–3840) |
height | number | 800 | Viewport height (240–2160) |
fullPage | boolean | false | Capture the full scrollable page |
quality | number | 80 | JPEG/WebP quality (1–100, default 80) |
delay | number | 0 | Delay before capture in ms (0–10000) |
darkMode | boolean | false | Emulate dark mode |
deviceScaleFactor | number | 2 | Device pixel ratio (1–3). 2× Retina by default |
blockAds | boolean | true | Block ads and trackers |
blockResourceTypes | string[] | — | Block: "font", "image", "media", "stylesheet", "other" |
timeout | number | 30 | Page load timeout in seconds (5–60) |
waitUntil | string | "networkidle2" | Wait strategy: "load", "domcontentloaded", "networkidle0", "networkidle2" |
waitForSelector | string | — | CSS selector to wait for before capture |
bestAttempt | boolean | true | Return best-effort screenshot on timeout |
selector | string | — | Capture a specific element by CSS selector |
import { Rendex, RendexApiError, RendexNetworkError } from "@copperline/rendex";
const rendex = new Rendex("your-api-key");
try {
await rendex.screenshot({ url: "https://example.com" });
} catch (error) {
if (error instanceof RendexApiError) {
// API returned an error
console.error(error.errorCode); // "RATE_LIMITED", "VALIDATION_ERROR", etc.
console.error(error.statusCode); // 429, 400, etc.
console.error(error.requestId); // For debugging with Rendex support
console.error(error.details); // Validation details (if any)
} else if (error instanceof RendexNetworkError) {
// Network failure (DNS, timeout, connection refused)
console.error("Network error:", error.message);
}
}
| Code | HTTP Status | Description |
|---|---|---|
VALIDATION_ERROR | 400 | Invalid request parameters |
INVALID_URL | 400 | URL failed SSRF validation |
TIMEOUT | 408 | Page took too long to load |
CAPTURE_FAILED | 500 | Browser rendering error |
RATE_LIMITED | 429 | Rate limit exceeded |
USAGE_EXCEEDED | 429 | Monthly credit limit reached |
MISSING_API_KEY | 401 | No API key provided |
INVALID_API_KEY | 401 | API key verification failed |
MIT - Copperline Labs LLC
FAQs
Official TypeScript SDK for Rendex — render HTML or Markdown to images, generate PDFs, capture screenshots, and monitor pages for changes with Rendex Watch
The npm package @copperline/rendex receives a total of 9 weekly downloads. As such, @copperline/rendex popularity was classified as not popular.
We found that @copperline/rendex demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.