Microlink vs Puppeteer for automated website screenshots
Compare Microlink’s managed screenshot API with Puppeteer’s browser control, including code, tradeoffs, costs, and when ScreenshotNeo may fit better.
Short answer: choose Microlink when you want to send a request to a managed screenshot API and avoid operating the browser fleet. Choose Puppeteer when you need direct JavaScript control over the browser and are prepared to install, deploy, and maintain it. Neither is universally faster or better: the right choice depends on the page state you need, the control your workflow requires, and who will run the browser.
If you want a managed screenshot API with consent-banner cleanup and billing that excludes failed or unclean captures, consider ScreenshotNeo first. Its API and MCP server are aimed at developers who want screenshots without setting up browser execution.
1. What you are comparing
| Option | Execution model | Good fit when | You own |
|---|---|---|---|
| ScreenshotNeo | Hosted screenshot API or MCP server | You want a managed request/response capture, cleanup of common consent UI, and explicit verdict and billing headers. | Your request options and API key; ScreenshotNeo runs the browser. |
| Microlink | Hosted screenshot API | You want a managed browser fleet and a documented HTTP request flow that returns screenshot asset metadata. | Request design, plan selection, and how you consume the returned asset. |
| Puppeteer | JavaScript library controlling Chrome or Firefox | You need custom browser automation, direct control of page state, or ownership of the execution environment. | Browser installation, runtime, deployment, concurrency, retries, and maintenance. |
Microlink’s screenshot guide describes rendering a URL in a headless browser, capturing the viewport or a configured screenshot, storing the image on a CDN, and returning asset metadata such as URL, dimensions, format, and size. Puppeteer is a JavaScript library for controlling Chrome or Firefox; it runs headless by default. Microlink screenshot guide · Puppeteer documentation
2. Decision in one minute
- Choose ScreenshotNeo first if the main job is to get clean screenshots from URLs through an API or an AI agent. Consent banners, newsletter popups, and chat widgets from supported platforms are removed before capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. The verdict and billing response headers identify the result.
- Choose Microlink if you want a managed screenshot API and its documented request and output model matches your workflow. Microlink handles the browser fleet and describes edge caching.
- Choose Puppeteer if the capture requires arbitrary JavaScript automation, a complex sequence of actions, or a browser environment you need to own and customize.
Before deciding, list the exact page state you need: viewport or full page, an element crop, authentication, a click or scroll, a wait condition, output format, and expected volume. Then check whether the hosted service exposes those controls or whether you need Puppeteer’s lower-level browser access.
3. Puppeteer: complete local screenshot example
This example installs Puppeteer with its compatible Chrome download, opens a URL, sets a viewport, waits for the page load event, and writes a PNG. Save it as screenshot.mjs.
import puppeteer from 'puppeteer';
const url = process.argv[2] ?? 'https://example.com';
const output = process.argv[3] ?? 'screenshot.png';
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto(url, { waitUntil: 'load', timeout: 30_000 });
await page.screenshot({ path: output, type: 'png' });
console.log(`Saved ${output}`);
} finally {
await browser.close();
}
npm init -y
npm install puppeteer
node screenshot.mjs https://example.com screenshot.png
For deployment, pin the Puppeteer version and use its matching browser installation. Puppeteer normally downloads a compatible Chrome; puppeteer-core is the alternative when you manage the browser executable yourself. Follow the official configuration guide for executable selection and defaults.
Capture full page, a selected element, or a mobile viewport
Replace the screenshot call as needed. Full-page capture can create very tall images, so consider output size and memory. Element capture requires the selector to exist and be visible; wait for it explicitly.
// Full document, including content beyond the initial viewport
await page.screenshot({ path: 'full-page.png', fullPage: true });
// A specific element
const card = await page.waitForSelector('.product-card', { timeout: 10_000 });
if (!card) throw new Error('Product card was not found');
await card.screenshot({ path: 'product-card.png' });
// Mobile-sized viewport (viewport emulation, not proof of a physical device)
await page.setViewport({ width: 390, height: 844, deviceScaleFactor: 2 });
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });
await page.screenshot({ path: 'mobile.png' });
Prepare the page before capturing
Use Puppeteer’s page APIs to authenticate, click, scroll, or wait for application-specific readiness. Prefer a meaningful selector or application signal over a fixed sleep when possible. A network-idle condition can be unsuitable for pages with persistent requests, analytics, or streaming content.
// Example: wait for a known page state, then capture
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });
await page.waitForSelector('[data-testid="report-ready"]', { timeout: 20_000 });
await page.locator('button.accept').click().catch(() => {});
await page.screenshot({ path: 'ready.png', fullPage: true });
The optional click above tolerates a missing button; do not suppress errors for actions that are required to produce the intended state. For authenticated pages, set cookies or use the relevant login flow before capture, and protect credentials in your runtime configuration. Keep page actions deterministic: selectors may be absent, duplicated, delayed, or changed by a site redesign.
4. Microlink: when an HTTP screenshot API fits
Microlink is the hosted option in this comparison. Its screenshot guide documents enabling screenshots with screenshot: true and screenshot-specific options, including full-page and element capture. The service renders the page and returns asset metadata. See the screenshot guide for the current request syntax and supported options, and the API page for current plans and service details.
Use the vendor’s current documentation to construct the exact request rather than copying an old endpoint or parameter spelling into production. The research for this article establishes the screenshot: true option and the response asset metadata, but does not establish a specific request URL or authentication format. That matters for runnable client code: a fabricated endpoint would look useful while failing in practice. Once you have the documented request URL and parameters, send it from cURL, Python, or Node.js with the same standard HTTP clients you use elsewhere, then consume the returned asset URL or binary output as documented.
Microlink’s browser automation material describes device emulation, navigation and selector waits, clicks, scrolling, and scripts before capture. Confirm the current option names and plan constraints in its automation documentation before depending on a particular interaction in a production workflow.
5. Options and capture requirements to compare
| Requirement | What to check | Puppeteer approach |
|---|---|---|
| Viewport screenshot | Viewport width and height; device scale; output type | Set the viewport and call page.screenshot(). |
| Full-page image | Lazy-loaded content, very long pages, image dimensions | Scroll or otherwise trigger lazy content if required, then use fullPage: true. |
| Element crop | Selector stability, visibility, and whether the element is inside a frame | Find the element and call its screenshot method. |
| Interactions | Clicks, scrolling, scripts, and the exact expected page state | Use browser/page APIs and assert that the resulting state is correct. |
| Wait strategy | Whether load, DOM readiness, a selector, or application readiness is meaningful | Choose a navigation condition plus an explicit readiness signal. |
| Authenticated content | Credential handling, cookie scope, session lifetime, and data policy | Set cookies or automate sign-in in a protected environment. |
| Operations | Concurrency, queueing, browser reuse, retries, and cleanup | Manage browser processes and job isolation in your service. |
Microlink and ScreenshotNeo expose options through a service request; Puppeteer exposes browser control through code. Map the needed capture state to the current service documentation before selecting a hosted tool. Do not assume an option exists just because the other product offers it.
6. Cost, performance, and reliability
Microlink pricing
The Microlink API page checked for this research advertised a free plan of 25 requests per day, Pro at $49 per month with approximately 46,000 monthly requests, and a 99.9% uptime SLA on paid plans. These are vendor-published figures checked on October 3, 2026, not independent measurements; pricing, quotas, and SLA wording can change. Confirm the current plan page before budgeting. Microlink API and plans
Puppeteer total cost
Puppeteer has no comparable hosted plan in the reviewed sources. Include compute, browser downloads and updates, queueing, storage, observability, retry capacity, and engineering time in your estimate. Cost per screenshot depends on your workload and infrastructure, so a local library is not automatically cheaper than an API.
Compare latency with your own workload
The available research did not establish an independent Microlink-versus-Puppeteer speed benchmark. Measure representative pages in your own environment: separate queue time, navigation time, wait time, rendering time, and image transfer; repeat across cold and warm runs; record failures as well as successful captures. Avoid choosing based on a vendor’s response-time claim as if it were a head-to-head result.
Reliability practices
- Set an overall job deadline and bounded navigation and selector timeouts.
- Retry only transient failures, with a limit and backoff; do not retry a deterministic missing selector indefinitely.
- Use a fresh page or isolated context for each job that handles different users or credentials.
- Always close pages and browsers in cleanup paths. Watch for orphaned browser processes and memory growth.
- Validate the output: check that it is non-empty, has the expected dimensions, and represents the intended page state.
- For hosted services, verify current service commitments, data handling, retention, and rate limits for the plan you will use. The reviewed material does not establish a universal security or reliability ranking.
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Puppeteer cannot find Chrome | Browser installation does not match the package or deployment image. | Install Puppeteer with its compatible browser, or configure the executable path when using puppeteer-core. Check the official configuration guide. |
| Navigation times out | The site is slow, keeps connections open, or the chosen navigation condition never settles. | Set an explicit timeout, choose a suitable readiness condition, and wait for a page-specific selector. Avoid treating network idle as universal. |
| Screenshot is blank or incomplete | Capture happened before app rendering, a client-side error occurred, or a required interaction was missed. | Wait for an application readiness selector, inspect page errors and console output, and verify the expected content before capture. |
| Lazy images are missing | Images load only after scrolling into view. | Scroll through the page or trigger the relevant content before the final full-page capture; verify the result on long pages. |
| Element screenshot fails | The selector is absent, hidden, ambiguous, or inside a frame. | Wait for the selector, check visibility and uniqueness, and target the correct frame where applicable. |
| Capture differs between runs | Dynamic ads, animations, clocks, random content, fonts, or responsive layout changed. | Use a stable viewport, disable or wait for animations where appropriate, wait for fonts and key content, and control page data when possible. |
| Hosted API returns an error or unexpected asset | Request option, quota, URL, or plan behavior may differ from the current documentation. | Check the response and current provider docs, validate the target URL, and confirm the plan limit before retrying. |
| Jobs consume too much memory | Pages or browser processes are not closed, or full-page captures are very large. | Close resources in finally, bound concurrency, and reduce image dimensions or split the workflow when possible. |
8. Or skip the browser setup
For the managed alternative, ScreenshotNeo takes a URL in one GET request and returns an image or PDF. It removes supported cookie and consent banners, newsletter popups, and chat widgets before the shot; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing result. An MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo API documentation. cURL example:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000. Sign up free for ScreenshotNeo.
9. Frequently asked questions
Can Microlink replace Puppeteer for every browser workflow?
No. A hosted API is a better fit when its documented request options cover the required capture. Complex, long-lived interactive sessions or workflows that need arbitrary browser control may fit Puppeteer better.
Is Puppeteer only for screenshots?
No. It is a browser-control library; screenshots are one capability. That flexibility comes with responsibility for running and maintaining the browser environment.
Which should I use for a high-volume crawl?
Estimate volume and operational effort, then verify limits and costs for the hosted plan. Microlink says its API may not suit crawling thousands of pages by following links; Puppeteer gives you control but requires you to operate the crawl infrastructure. Microlink API guidance
Do the reviewed sources prove one produces better images?
No independent head-to-head quality or speed result was established. Compare captures of your own target pages using the same viewport, readiness condition, and output requirements.
