Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use Ferrum when you need Ruby to control a local Chrome or Chromium browser. It can open a URL, wait for dynamic content, and save PNG, JPEG, or WebP screenshots, including full-page, selector, and rectangular-area captures. For Capybara suites, Cuprite provides a Ferrum-based driver. If you would rather avoid browser installation and maintenance, a hosted renderer such as ScreenshotNeo accepts one HTTP request and can return an image or PDF.

Choose the rendering approach first

Your choice depends mainly on where Chrome runs and how much control you need.

Approach Best fit What you operate
Ferrum Ruby scripts, jobs, and applications needing direct browser control Chrome or Chromium and its runtime dependencies
Cuprite Capybara feature and system tests Chrome or Chromium through Ferrum
FerrumPdf Ruby workflows that render HTML or URLs to PDF or images Its documented Ruby rendering stack
Hosted HTML-to-image API Deployments where you do not want a browser in each worker API credentials, request handling, and data-transfer policy

The documentation for Ferrum and its screenshot implementation is version-sensitive. Pin the gem and verify option names against the branch or release you deploy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture a website with Ferrum

Prerequisites

  • Ruby and the Ferrum gem.
  • A Chrome or Chromium binary available in PATH, or the browser path configured using Ferrum’s documented option.
  • Permission for the target site and network access from the machine running the script.

Ferrum communicates with Chrome over the Chrome DevTools Protocol; it does not require Selenium, WebDriver, or ChromeDriver. A minimal script is:

#1 Best Overall
require "ferrum"

browser = Ferrum::Browser.new
browser.go_to("https://example.com")
browser.screenshot(path: "example.png")
browser.quit

The browser opens the page, captures the current viewport, and writes a PNG. Always close the browser in production code, including when navigation or capture raises an exception:

require "ferrum"

browser = Ferrum::Browser.new
begin
  browser.go_to("https://example.com")
  browser.screenshot(path: "example.webp", format: :webp)
ensure
  browser.quit
end

Wait for JavaScript and images

A navigation response does not guarantee that a single-page application has finished rendering. Wait for a meaningful selector, or use a controlled delay when no stable selector exists:

browser.go_to("https://example.com/dashboard")
browser.at_css("[data-page-ready]")
browser.screenshot(path: "dashboard.png", full: true)

For pages that load images lazily, scroll or use the page’s own readiness signal before requesting a full capture. A full-page screenshot is different from a viewport screenshot: it includes the document’s full scrollable height, while the default captures only the visible viewport.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Ferrum screenshot options

Ferrum’s implementation documents PNG, JPEG/JPG, and WebP output. It also supports viewport and full-page captures, CSS-selector or rectangular-area captures, scaling, background color, writing directly to a file, and returning Base64 data.

Output formats and scale

browser.screenshot(path: "page.jpg", format: :jpeg, quality: 85)
browser.screenshot(path: "page.webp", format: :webp, scale: 2)

Use a higher scale for retina-style assets, but expect larger files and more memory use. JPEG quality applies to lossy JPEG output; PNG is lossless and WebP can be used when your consumer supports it.

Full page, selector, and area captures

# Entire document
browser.screenshot(path: "full.png", full: true)

# One element identified by CSS selector
browser.screenshot(path: "hero.png", selector: ".hero")

# A rectangular region (coordinates are page pixels)
browser.screenshot(path: "region.png", area: { x: 0, y: 0, width: 800, height: 600 })

Selector capture is useful for cards, invoices, and test fixtures. Make sure the selector resolves to the intended element and that fonts and images have finished loading.

Backgrounds and Base64

data = browser.screenshot(format: :png, encoding: :base64, background_color: "#ffffff")
File.binwrite("page.b64", data)

Check the installed Ferrum version for the exact return encoding and option spelling before relying on Base64 in an API response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Convert an HTML string to an image

To render HTML rather than a public URL, create a page in the browser and set its document content. A data URL is simple for small, self-contained markup:

require "ferrum"
require "cgi"

html = <<~HTML
  <!doctype html>
  <html><head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>body{font-family:system-ui;margin:32px} .card{padding:24px;border:1px solid #ddd}</style>
  </head><body>
    <div class="card"><h1>Invoice</h1><p>Rendered by Ruby</p></div>
  </body></html>
HTML

browser = Ferrum::Browser.new
begin
  browser.go_to("data:text/html,#{CGI.escape(html)}")
  browser.screenshot(path: "invoice.png", selector: ".card")
ensure
  browser.quit
end

For larger documents, serve the HTML from a local route so relative CSS, fonts, and images resolve normally. External resources may be blocked by network policy, authentication, CORS behavior, or the target server.

Generate a PDF instead of an image

Ferrum exposes PDF generation as a separate method. A PDF is a paginated document, not a screenshot image, so choose it when selectable text, print layout, or paper dimensions matter.

browser.go_to("https://example.com/invoice")
browser.pdf(path: "invoice.pdf", format: "A4", landscape: false)

Page size, margins, and other print options vary by Ferrum version; consult the versioned API documentation before shipping a print pipeline.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Cuprite with Capybara

Cuprite is a pure-Ruby Capybara driver built on Ferrum. It is a natural choice for system or feature tests that already use Capybara:

require "capybara"
require "capybara/cuprite"

Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(app, js_errors: true)
end
Capybara.default_driver = :cuprite

session = Capybara::Session.new(:cuprite)
session.visit("https://example.com")
File.binwrite("capybara.png", session.save_page_screenshot(nil))

Cuprite’s README documents a Base64 screenshot method and warns that some Selenium conventions behave differently. Audit any Selenium-specific waits, driver calls, and browser options during migration rather than assuming drop-in compatibility.

Other Ruby rendering options

FerrumPdf

FerrumPdf is described as a Ruby option for rendering HTML or a URL to PDF and screenshots. The available documentation establishes that use case, but not comparative reliability, maintenance, or performance against Ferrum. Evaluate it against your exact templates and deployment environment.

Hosted Ruby clients

The official Ruby client for the html2img service documents URL screenshots, HTML rendering, full-page captures, selector capture, and PDF output. A hosted client moves browser installation out of your workers, but review its current authentication, retention, pricing, latency, and privacy terms before sending sensitive HTML.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. It accepts one GET request and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.

Use the documented request from Ruby (see the ScreenshotNeo API documentation):

require "net/http"
require "uri"

uri = URI("https://api.screenshotneo.com/v1/shot")
uri.query = URI.encode_www_form(access_key: "YOUR_API_KEY", url: "https://stripe.com")
response = Net::HTTP.get_response(uri)
raise "HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
File.binwrite("shot.webp", response.body)

The same endpoint supports full-page and element capture, dark mode, device presets or custom viewports, retina scale, PDF paper settings, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

Plans include 1,000 free shots per month with no card; Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to start.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting Ruby captures

Chrome cannot be found

Install Chrome or Chromium and confirm the executable is on PATH. In containers, install the browser and required shared libraries, or pass Ferrum’s documented browser path option.

The screenshot is blank or incomplete

Wait for a page-specific selector, increase the viewport, and confirm that the page’s JavaScript and external assets are reachable from the worker. For lazy images, trigger the page’s loading behavior before a full capture.

A selector capture fails

Check that the selector exists after navigation, is unique, and is visible. Use a stable data-* attribute instead of a generated class name.

Fonts differ from development

Install the same fonts in every runtime, wait for web fonts to load, and avoid capturing before the font-loading promise resolves. Container images often lack desktop fonts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capybara tests fail after switching from Selenium

Review Cuprite’s documented differences and replace Selenium-only driver calls with Capybara APIs or Ferrum-supported operations.

Requests hang

Set navigation and script timeouts, close browsers in an ensure block, and limit concurrency to the CPU and memory available. Reuse a browser only when isolation between jobs is acceptable.

Performance, reliability, and security decisions

  • Reuse versus isolation: Reusing one browser reduces startup overhead; separate browser instances reduce cross-request state leakage.
  • Concurrency: Each active page consumes memory. Measure your templates before increasing worker count.
  • Determinism: Fix viewport, timezone, locale, fonts, and animations for stable visual tests.
  • Network safety: Treat user-supplied URLs as SSRF input. Restrict private IP ranges, protocols, redirects, and credentials.
  • Data handling: Local Ferrum keeps rendering in your environment. A hosted API sends the requested URL or HTML to a service, so inspect retention and compliance terms.
  • Cost: Local rendering costs infrastructure and maintenance. Hosted pricing and cache behavior change over time; use the provider’s current terms and response billing headers.

FAQ

Can Ferrum take a screenshot without Selenium?

Yes. Ferrum controls Chrome or Chromium over CDP and does not require Selenium, WebDriver, or ChromeDriver.

Is a full-page screenshot the same as a PDF?

No. A full-page screenshot is an image of the document; PDF output follows print pagination and paper settings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which option fits a Capybara test suite?

Cuprite, because it is documented as a Capybara driver built on Ferrum.

Can I capture only one HTML element?

Yes. Ferrum supports CSS-selector capture, and ScreenshotNeo provides selector capture through its API.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.