Free tools Windows power users keep installed
One-click scans. No signup required.
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 PhantomJS’s webpage module: set a phone-sized page.viewportSize, optionally set a mobile user-agent before page.open(), wait for a successful load, then call page.render(). The result is a repeatable mobile-width screenshot, not proof of identical rendering on a current iPhone or Android device.
What PhantomJS can and cannot emulate
PhantomJS 2.1.1 is legacy command-line browser software. Its documented controls let you choose a CSS viewport, request a user-agent-sensitive version of a page, select a capture rectangle and write an image or PDF. They do not document device-pixel-ratio control, touch input, or a switch that emulates a particular modern handset.
Therefore, describe the output accurately: it is a mobile-width or responsive screenshot. A real-device test is still needed when layout or behavior depends on touch events, high-density displays, browser-specific APIs, or a current mobile rendering engine.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Prerequisites and the capture workflow
- Install the PhantomJS executable and make sure
phantomjsis on your command path. - Create a JavaScript file that imports
webpage. - Choose the CSS viewport width and height you want to review.
- Set
page.settings.userAgentbefore the firstpage.open()call if the server changes markup for mobile clients. - Render only after the open callback reports
success.
The official PhantomJS screen-capture, command-line, render, page-automation, settings, evaluate and quick-start references document this sequence and the APIs used below.
#1 Best Overall
Basic mobile screenshot script
Save this as capture.js. The 390 × 844 values and user-agent string are illustrative inputs; they are not an official iPhone preset or a guarantee of device equivalence.
var page = require('webpage').create();
// CSS viewport dimensions to inspect.
page.viewportSize = { width: 390, height: 844 };
// Set this before page.open() when the server uses the UA to choose content.
page.settings.userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1';
page.open('https://example.com/', function (status) {
if (status !== 'success') {
console.log('Unable to load the page');
phantom.exit(1);
return;
}
page.render('mobile.png');
phantom.exit();
});
Run it from the same directory:
phantomjs capture.js
A successful run writes mobile.png. The render filename selects the format; documented formats include PNG, JPEG, BMP, PPM and PDF. GIF support depends on the Qt build.
Control viewport, crop and output
Choose the CSS viewport
page.viewportSize controls the layout viewport—the width against which responsive CSS media queries are evaluated. Set it before navigation:
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →page.viewportSize = { width: 375, height: 812 };
Use dimensions that match the scenario you are reviewing, rather than assuming that one width represents every phone. Changing the viewport changes layout; it does not add touch support or change the browser engine.
Rank #2
Capture a defined rectangle
page.clipRect limits the rendered area. This is useful for a card, hero region or fixed-size review surface:
page.clipRect = { top: 0, left: 0, width: 390, height: 844 };
A single viewport render should not automatically be called a full-document capture. Set bounds deliberately and inspect the result. If you need content below the initial viewport, determine suitable capture bounds for that page and verify the output.
Select a file format
Change only the extension when the required format is supported:
page.render('mobile.jpg');
// or
page.render('mobile.pdf');
JPEG is useful where file size matters; PNG preserves crisp text and transparency-related detail. PDF output follows PhantomJS’s render API and is not a substitute for validating a responsive image capture.
Rank #3
Make asynchronous pages complete before rendering
The basic example renders in the page.open() callback, which confirms navigation succeeded. Modern applications often populate the DOM after that callback. PhantomJS documentation does not define a universal delay that works for every site, so use a site-specific readiness condition and verify the image.
Poll for a known element
page.evaluate() runs JavaScript in the page context and returns serializable values. It can test whether an application-specific element exists:
var page = require('webpage').create();
page.viewportSize = { width: 390, height: 844 };
page.settings.userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1';
var deadline = Date.now() + 15000;
function waitForContent() {
var ready = page.evaluate(function () {
return !!document.querySelector('[data-screenshot-ready]');
});
if (ready) {
page.render('mobile-ready.png');
phantom.exit();
} else if (Date.now() > deadline) {
console.log('Timed out waiting for the page-specific ready marker');
phantom.exit(2);
} else {
setTimeout(waitForContent, 250);
}
}
page.open('https://example.com/', function (status) {
if (status !== 'success') {
console.log('Unable to load the page');
phantom.exit(1);
return;
}
waitForContent();
});
Replace [data-screenshot-ready] with a marker your application sets after its data and images are ready. If no reliable marker exists, use a bounded, site-specific delay and inspect several captures; never assume a fixed sleep works universally.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallUser-agent selection and its limits
Set page.settings.userAgent before page.open(). The settings documentation says these values take effect during the initial open call, so changing the string after navigation may not change the response you already received.
Rank #4
A mobile user-agent can cause a server to send mobile-oriented markup, while the narrow viewport triggers responsive CSS. Those two controls are independent: a site can use either one, both, or neither. They still do not establish touch capability, modern JavaScript compatibility, device-pixel-ratio behavior or parity with a current handset.
Common failures and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
Unable to load the page |
DNS, TLS, network, redirect or site availability problem. | Open the URL from the same machine, check the exact URL and retry. Keep the status check and do not render a failed page. |
| Desktop layout in the image | Viewport is wide, or the server did not receive a mobile user-agent. | Set page.viewportSize before opening and set the user-agent before page.open(). Confirm the page’s own responsive breakpoints. |
| Blank or partially populated image | Rendering occurred before asynchronous content was ready. | Poll for a page-specific DOM marker with page.evaluate(), or use a bounded delay selected for that site; then inspect the output. |
| Only the top portion appears | The capture rectangle covers only the viewport or a short clip. | Set page.clipRect to the intended region and verify its dimensions. Do not label a viewport capture full-page without checking it. |
| Unexpected dialogs or overlays | Consent banners, chat widgets or application modals cover the page. | Handle the page state in your script where possible, or use a capture service that removes common overlays before billing and capture. |
| Modern site scripts fail | PhantomJS’s engine is old and may not support current browser features. | Use PhantomJS only for compatible legacy targets, or capture with a maintained browser/service when current-engine fidelity is required. |
Repeatable capture checklist
- Define the CSS width and height, and record them with the output.
- Decide whether the server needs a mobile user-agent.
- Set viewport and user-agent before the first
page.open(). - Check the callback status before calling
page.render(). - Wait for a known application state when content loads asynchronously.
- Choose a clip rectangle or document bounds intentionally.
- Use the extension that matches the required output format.
- Review the image for overlays, missing images, horizontal overflow and content below the fold.
- Repeat at each target width; one narrow viewport is not a device compatibility matrix.
Performance, reliability and cost considerations
PhantomJS runs locally, so runtime depends on your machine, network, target site and any readiness polling. A long timeout can hide a broken page; a short one can capture incomplete content. Record the URL, viewport, user-agent, timestamp and readiness rule alongside artifacts so differences are diagnosable.
For modern, JavaScript-heavy sites, a maintained browser engine is generally a better technical fit than this legacy engine. If you need scheduled or distributed captures, also account for process isolation, retries, storage, authentication and the cost of running browser workers. PhantomJS itself does not provide a hosted usage meter or a guarantee that failed loads are free.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteOr skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One request returns a PNG, JPEG, WebP or PDF, and its capture options include mobile viewport sizes, 12 device presets, custom user-agents, full-page loading, selector clips, waits, custom CSS and JavaScript, cookies, headers, geolocation, timezone, blocking rules, caching and async webhooks. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.
Using the ScreenshotNeo API documentation, a one-call mobile capture looks like this:
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)
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}`);
The MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. Every feature is available on every plan: 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
When to choose each approach
| Requirement | PhantomJS script | ScreenshotNeo |
|---|---|---|
| Local, offline-controlled workflow | Yes, provided the legacy engine can load the site. | Hosted request; requires API access. |
| CSS viewport and user-agent | Supported through viewportSize and settings.userAgent. |
Supported, plus device presets and additional capture controls. |
| Consent and overlay cleanup | Must be handled by your script or page state. | Built-in removal of known consent, newsletter and chat overlays. |
| Modern browser or touch fidelity | Not established by the documented API. | Use the service’s documented options, but validate any requirement that depends on a specific real handset. |
| Billing on failed pages | Local execution; no service billing model. | Failed loads, bot checks, blank pages, timeouts and cache hits are not billed. |
Frequently Asked Questions
Does PhantomJS create an actual iPhone screenshot?
No. It can combine a phone-like CSS viewport with a mobile user-agent, but the documented API does not provide full device metrics, touch emulation or current mobile-browser parity.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Where should the user-agent be assigned?
Assign page.settings.userAgent before the first page.open(); the settings apply during the initial open call.
Can I capture a whole page with page.render()?
Only if you deliberately set and verify capture bounds that include the required document area. A normal viewport render is not automatically a guaranteed full-document screenshot.
Quick Recap
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.

