ScreenshotNeo

BlogComparisons

wkhtmltoimage vs Chrome for Generating Website Thumbnails in India

Choose Chrome for new thumbnail pipelines that render modern, JavaScript-heavy sites. Keep wkhtmltoimage for suitable legacy workflows, and benchmark on your own pages and deployment environment.

By the ScreenshotNeo team4 October 20269 min read

Short answer: For a new website-thumbnail pipeline in India, choose headless Chrome when your targets use current CSS or JavaScript-heavy pages. Keep wkhtmltoimage when you already have a stable legacy workflow and its output and security controls meet your needs. This is a documentation-based recommendation, not a comparative benchmark: measure your own target pages and deployment before making claims about speed, memory, fidelity, or cost.

Both can render without a visible browser window. They are different rendering stacks: wkhtmltoimage uses Qt WebKit, while Chrome Headless captures through Chrome and provides documented screenshot and viewport controls. India affects operational decisions such as worker location, network path, locale, fonts, and data handling; the available sources do not establish an India-specific renderer winner or hosting recommendation.

1. What differs between wkhtmltoimage and Chrome?

Question wkhtmltoimage Chrome Headless
Rendering stack Qt WebKit, exposed through the wkhtmltopdf project’s command-line tools. Chrome’s rendering engine, invoked with Chrome’s headless command-line options.
Dynamic pages The project maintainer recommends a modern browser automation tool for dynamic JavaScript sites. A stronger starting point for current sites, but you must still define and validate page readiness.
Capture controls Screen width, crop rectangle, format, JavaScript enablement, and JavaScript delay are documented settings. Screenshot output, window size, timeout, and virtual-time budget are documented CLI controls.
Maintenance context The project status page describes an old Qt/WebKit lineage and says the planned 0.13 work stalled. Its history is dated; it is not a live inventory of every downstream build. Chrome’s CLI documentation describes current headless capture usage. Keep the browser runtime maintained in your deployment.
Performance and cost No comparative speed, memory, fidelity, or cost figures are established by the reviewed sources. Benchmark both on your environment if these determine the choice.

The project describes wkhtmltoimage and wkhtmltopdf as open-source LGPLv3 command-line tools that run headlessly, without a display service. Chrome likewise documents headless use for server environments. See the wkhtmltopdf project and Chrome Headless command-line reference.

2. Choose based on your pages and constraints

Choose Chrome for a new pipeline when

  • Pages depend on current browser behavior, client-side rendering, or JavaScript-driven content.
  • You want Chrome’s documented viewport and screenshot command-line controls.
  • You can pin and update the browser runtime as part of your worker deployment.

Keep wkhtmltoimage when

  • An existing, known set of pages renders acceptably and you need to preserve that established output.
  • Your pages do not rely on modern dynamic behavior that the renderer handles poorly.
  • You have reviewed the toolchain’s maintenance and security posture for your workload.

Do not choose on the assumption that Chrome is always faster or that either tool always produces a better thumbnail. Those outcomes depend on page content, readiness, viewport, hardware, concurrency, and runtime configuration.

3. Capture a thumbnail with headless Chrome

Install Chrome or Chromium using the packaging method supported by your operating system, then invoke its executable. The example below writes a screenshot at a fixed window size; replace the executable path, URL, and dimensions for your environment.

google-chrome --headless --no-sandbox --disable-gpu \
  --window-size=1200,630 \
  --timeout=10000 \
  --screenshot=thumbnail.png \
  https://example.com

On systems where the executable is named chromium or chromium-browser, use that name. The --no-sandbox flag is included only because some container examples run as root; it weakens Chrome’s process isolation. Prefer running as a non-root user with the sandbox enabled when your environment supports it. If you must disable the sandbox, confine the worker and its network and filesystem access.

--window-size=WIDTH,HEIGHT sets the capture viewport. The Chrome documentation’s sample dimensions are examples, not thumbnail recommendations. Choose dimensions that match the target site’s responsive breakpoints and your intended card ratio. --timeout sets a maximum wait before capture; it does not prove all asynchronous content is ready. --virtual-time-budget can advance time-dependent JavaScript in virtual time, but it also does not guarantee every arbitrary page has finished loading.

google-chrome --headless \
  --window-size=1200,630 \
  --timeout=10000 \
  --virtual-time-budget=3000 \
  --screenshot=thumbnail.png \
  https://example.com

For reliable production output, wrap the browser in an automation flow that waits for a page-specific ready signal or a stable condition, then captures. Ensure fonts and important images have loaded; use a bounded timeout so a page cannot occupy a worker indefinitely. Chrome’s CLI flags are useful for simple captures, while a browser automation library is generally more suitable when each page needs tailored readiness logic.

4. Capture with wkhtmltoimage

Install a build appropriate for your platform, then use the command-line tool. Check the options available in that specific build; packaging and downstream builds can vary.

wkhtmltoimage \
  --width 1200 \
  --javascript-delay 3000 \
  https://example.com \
  thumbnail.png

The width controls the rendering screen width. The JavaScript delay gives scripts time after page loading, but a fixed delay is not a page-specific readiness check. wkhtmltoimage also documents crop coordinates and dimensions, output format, and JavaScript settings. The underlying image settings list screenWidth, crop.left, crop.top, crop.width, crop.height, and formats jpg, png, bmp, or svg. Refer to the project’s image settings documentation and verify command-line spelling for your installed version.

For a crop, calculate the rectangle from the rendered page geometry and confirm it against sample pages. A crop width and height determine the captured region; they do not automatically make the page responsive at a desired thumbnail breakpoint. Set the screen width to influence responsive layout, then crop if needed.

5. Make a fair renderer comparison

If you are deciding between the two for an India-hosted service, compare them under the same conditions. A renderer comparison is only meaningful when both see the same page state and geometry.

  1. Select representative URLs: static pages, client-rendered pages, pages with delayed images, and pages that behave differently by locale or region.
  2. Fix viewport width and height, device scale, URL parameters, and any authentication or cookies.
  3. Define page readiness consistently. Prefer a page-specific signal; otherwise state the same bounded wait and acceptance criteria for both.
  4. Capture the same output dimensions and format. Compare whether the subject is visible, the layout matches the intended responsive breakpoint, fonts and images are present, and the crop is useful.
  5. Run at your expected concurrency on the actual worker hardware. Measure startup time, memory, throughput, failure rate, and output consistency yourself.
  6. Repeat from the deployment region and network path you intend to use. Treat region, target-site latency, locale, fonts, and data handling as validation requirements, not as established India-specific findings.

Do not compare captures taken at different viewport sizes or page-ready conditions and call the result a renderer benchmark. The research sources provide no comparable performance, memory, fidelity, or cost figures.

6. Security, reliability, and operating costs

Untrusted URLs and HTML

Rendering a URL or HTML supplied by a user is a security boundary. The wkhtmltopdf project’s maintainer warns specifically against using wkhtmltopdf with untrusted HTML and recommends sanitization and confinement, including considering Mandatory Access Control such as AppArmor or SELinux. That quoted warning names wkhtmltopdf. Since wkhtmltoimage belongs to the same Qt WebKit tool family, applying isolation to untrusted wkhtmltoimage workloads is a cautious operational inference, not a separate quoted warning.

For either renderer, isolate workers, set time and resource limits, restrict filesystem access, and consider outbound network controls to reduce exposure to malicious pages and server-side request forgery. Avoid passing secrets in pages or renderer arguments where process listings or logs could expose them.

Reliability

  • Bound navigation and capture time; fail and retry selectively rather than letting a stuck page block a worker.
  • Distinguish a successful browser process exit from a useful thumbnail: inspect output existence, dimensions, and whether expected page content is present.
  • Use a stable browser/tool version during a batch, and validate output when upgrading.
  • Keep concurrency within measured memory and CPU limits. No sourced resource figures are available, so size workers from your own observations.

Cost

Both are software options, but the sources do not provide a comparable cost model. Account for worker compute, storage, network traffic, browser/runtime maintenance, retries, and engineering time in your own estimate. No India-specific price or hosting conclusion is established here.

7. Troubleshooting

Symptom Likely cause What to try
Screenshot is blank or mostly empty Capture ran before client-side rendering completed, navigation failed, or the page rejected the request. Check the URL from the worker, inspect browser output and exit status, wait on a page-specific readiness condition, and record a bounded timeout.
Content is missing even though the page loaded Delayed scripts, lazy images, fonts, or asynchronous API requests were not ready at capture time. Wait for the relevant content or image state; use a page-specific signal. A fixed delay can help but is not a universal readiness guarantee.
Layout does not match the site thumbnail The viewport triggers a different responsive breakpoint, or the crop rectangle is wrong. Set the intended viewport explicitly. For wkhtmltoimage, verify screen width and crop coordinates; for Chrome, set window size and capture the intended viewport.
Chrome exits immediately or cannot start in a container Executable path, runtime dependencies, permissions, or sandbox configuration is incompatible with the container. Verify the installed binary and its dependencies, run as a suitably configured non-root user, and inspect stderr. Do not disable the sandbox without compensating isolation.
wkhtmltoimage differs from a current browser Its Qt WebKit-based rendering behavior differs from modern browser behavior, particularly on dynamic pages. Use Chrome for pages requiring current rendering behavior, or retain wkhtmltoimage only for a validated legacy workload.
Captures time out intermittently Slow target response, blocked third-party resource, infinite page activity, or too-short timeout. Log per-stage timing, bound resource waits, decide which resources are necessary, and retry only transient failures with a limit.
Worker resource use grows under load Unbounded concurrency, stuck pages, or renderer processes not being reaped. Cap concurrent captures, enforce process and job deadlines, reap child processes, and measure memory on representative pages.

8. Or skip the browser setup

For a managed screenshot call, ScreenshotNeo is the alternative to try first: it returns a screenshot or PDF from one API request and bills only clean shots. Its API supports PNG, JPEG, and WebP output, full-page capture, CSS selector capture, viewport and device settings, waits, custom headers and cookies, and other capture controls. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

Replace YOUR_API_KEY with your key. The Node.js example uses Bun’s file-writing helper; in Node.js, save the response body with await fs.promises.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())) after importing fs from node:fs. Check response headers such as X-Page-Verdict and X-Billed to distinguish clean captures from bot checks, blank pages, failed loads, and cache hits.

  • Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients.
  • The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Every feature is available on every plan.

Sign up free for 1,000 screenshots a month, with no card required.

9. FAQ

Does headless mean the renderer needs no display server?

The wkhtmltopdf project explicitly says its tools run headlessly without a display service, and Chrome documents headless operation. You still need the executable and its runtime dependencies installed.

Can I use a fixed wait for every page?

You can, but it may waste time on fast pages and still miss slow or asynchronously updated content. Prefer readiness conditions based on the page and cap the total wait.

Is one tool cheaper for an India deployment?

The reviewed sources do not establish renderer or India-specific pricing. Include compute, operations, maintenance, and engineering effort in a measured estimate for your deployment.

Which should I use for a new thumbnail service?

Start with Chrome for modern and dynamic pages, then validate representative pages under your actual workload. Use wkhtmltoimage when a legacy workflow is already proven for its target set and acceptable to operate.

Sources