webrenderly
v0.1.0
Published
CLI tool for rendering website screenshots in desktop, mobile, full-page, and custom viewport modes.
Downloads
110
Maintainers
Readme
Renderly
Renderly is a Playwright-based CLI and Node.js API for rendering website screenshots in fixed desktop, fixed mobile, full-page, and custom viewport modes.
It is designed for visual review of real website states:
- desktop 16:9 viewport screenshots
- desktop full-page screenshots from top to footer
- mobile 9:20 viewport screenshots
- mobile full-page screenshots
- custom viewport screenshots with exact width and height
- hash-anchor screenshots for specific website sections
Install
Run without installing globally:
npx renderly --url http://localhost:4173/index.html#results --device pc --type viewport -o out.pngInstall in a project:
npm install --save-dev renderlyThen run:
npx renderly --url http://localhost:4173/index.html --device mobile --type full-page -o screenshots/mobile-full.pngRenderly uses Playwright and Chromium under the hood.
Basic Command
renderly --url <url> --device <pc|mobile> --type <viewport|full-page|custom> -o <path>Example:
npx renderly --url http://localhost:3210/#pricing --device mobile --type full-page -o screenshots/pricing-mobile.pngCLI Options
| Option | Required | Values | Default | Description |
| --- | --- | --- | --- | --- |
| --url <url> | yes | http://..., https://... | none | Page URL to render. Hash anchors are supported, for example /#pricing. |
| --device <device> | yes | pc, mobile | none | Browser behavior profile. Controls mobile emulation, touch, and device scale factor. |
| --type <type> | yes | viewport, full-page, custom | none | Screenshot capture mode. |
| -o, --output <path> | yes | file path | none | Output image path. Parent directories are created automatically. |
| -w, --width <px> | only for custom | positive integer | none | Custom viewport width in CSS pixels. |
| -h, --height <px> | only for custom | positive integer | none | Custom viewport height in CSS pixels. |
| --wait-until <state> | no | load, domcontentloaded, networkidle | load | Navigation wait condition. |
| --timeout <ms> | no | positive integer | 30000 | Navigation timeout in milliseconds. |
| --delay <ms> | no | non-negative integer | 0 | Extra wait before screenshot after Renderly finishes its own page preparation. |
| --format <format> | no | png, jpeg | inferred | Output format. If omitted, .jpg and .jpeg use JPEG, everything else uses PNG. |
Device vs Screenshot Type
--device controls browser behavior.
--type controls screenshot size and capture behavior.
--device pc
Uses desktop browser behavior:
isMobile: false
hasTouch: false
deviceScaleFactor: 1--device mobile
Uses mobile browser behavior:
isMobile: true
hasTouch: true
deviceScaleFactor: 2Renderly saves screenshots in CSS pixels, so --type custom -w 800 -h 1600 produces an 800x1600 image even with --device mobile.
Screenshot Modes
Desktop 16:9 Viewport
npx renderly --url http://localhost:4173/index.html --device pc --type viewport -o screenshots/pc.pngCaptures:
1920x1080Use this for normal desktop hero/page-state review.
Desktop Full Page
npx renderly --url http://localhost:4173/index.html --device pc --type full-page -o screenshots/pc-full.pngStarts with a 1920x1080 desktop viewport, wakes lazy-loaded content by scrolling through the document, returns to the top, then captures the whole page from start to footer.
Mobile 9:20 Viewport
npx renderly --url http://localhost:4173/index.html --device mobile --type viewport -o screenshots/mobile.pngCaptures:
450x1000Use this for smartphone-style adaptive layout review.
Mobile Full Page
npx renderly --url http://localhost:4173/index.html --device mobile --type full-page -o screenshots/mobile-full.pngStarts with a 450x1000 mobile viewport, wakes lazy-loaded content by scrolling through the document, returns to the top, then captures the whole mobile page.
Custom Viewport
npx renderly --url http://localhost:4173/index.html --device pc --type custom -w 1440 -h 900 -o screenshots/pc-1440x900.png
npx renderly --url http://localhost:4173/index.html --device mobile --type custom -w 800 -h 1600 -o screenshots/mobile-800x1600.pngCustom mode captures the visible viewport only. It does not capture the full page.
--device still matters in custom mode:
--device pc --type custom -w 800 -h 1600renders as a desktop browser in an800x1600viewport.--device mobile --type custom -w 800 -h 1600renders as a mobile/touch browser in an800x1600viewport.
Rendering Specific Sections With Anchors
For specific parts of a website, prefer adding stable anchors in the site code and rendering by URL hash.
Example HTML:
<section id="results">
...
</section>Example command:
npx renderly --url http://localhost:4173/index.html#results --device pc --type viewport -o screenshots/results-pc.pngThis is more reliable than trying to crop screenshots manually or guessing scroll offsets.
Recommended anchor practice:
- Add stable
idvalues for important sections such ashero,pricing,results,features,faq, andfooter. - Keep anchors on real layout containers, not decorative inner elements.
- Use unique anchor names.
- If a fixed header covers the target, handle it in site CSS with
scroll-margin-top.
Example:
section[id] {
scroll-margin-top: 96px;
}Content Loading Behavior
Before saving a screenshot, Renderly prepares the page:
- Waits for page navigation according to
--wait-until. - Waits for document fonts.
- If the URL has a hash anchor, waits for the target to exist.
- For full-page screenshots, scrolls through the document to wake lazy-loaded content.
- For hash-anchor viewport screenshots, also scrolls through the page first so lazy content above the target can affect layout before the final anchor scroll.
- Waits for images to load or fail.
- Performs a final instant scroll to the hash target for viewport/custom captures.
- Waits for layout to settle.
- Saves the screenshot.
If your application renders content after API calls, animations, or delayed state changes, add --delay.
npx renderly --url http://localhost:4173/index.html#results --device pc --type viewport --delay 1000 -o screenshots/results.pngWait Modes
Default:
--wait-until loadUse load for most real websites. Many production sites keep analytics, video, tracking, or app requests open, so networkidle can time out.
Use domcontentloaded when you want the fastest possible capture and the page does not depend on late assets.
Use networkidle only when the page truly becomes quiet and you need that strict behavior.
npx renderly --url http://localhost:4173/index.html --device pc --type viewport --wait-until networkidle -o screenshots/quiet.pngRecommended Visual Test Matrix
Use more than one aspect ratio when the interface can shift, wrap, overflow, or reflow.
Minimum useful set:
npx renderly --url http://localhost:4173/index.html --device pc --type viewport -o screenshots/pc-1920x1080.png
npx renderly --url http://localhost:4173/index.html --device pc --type custom -w 1440 -h 900 -o screenshots/pc-1440x900.png
npx renderly --url http://localhost:4173/index.html --device pc --type custom -w 1366 -h 768 -o screenshots/pc-1366x768.png
npx renderly --url http://localhost:4173/index.html --device mobile --type viewport -o screenshots/mobile-450x1000.png
npx renderly --url http://localhost:4173/index.html --device mobile --type custom -w 390 -h 844 -o screenshots/mobile-390x844.png
npx renderly --url http://localhost:4173/index.html --device mobile --type custom -w 360 -h 800 -o screenshots/mobile-360x800.pngFor long pages, add full-page captures:
npx renderly --url http://localhost:4173/index.html --device pc --type full-page -o screenshots/pc-full.png
npx renderly --url http://localhost:4173/index.html --device mobile --type full-page -o screenshots/mobile-full.pngFor important sections, test anchors:
npx renderly --url http://localhost:4173/index.html#pricing --device pc --type viewport -o screenshots/pricing-pc.png
npx renderly --url http://localhost:4173/index.html#pricing --device mobile --type viewport -o screenshots/pricing-mobile.png
npx renderly --url http://localhost:4173/index.html#results --device pc --type viewport -o screenshots/results-pc.png
npx renderly --url http://localhost:4173/index.html#results --device mobile --type viewport -o screenshots/results-mobile.pngProgrammatic API
import { renderScreenshot } from "renderly";
await renderScreenshot({
url: "http://localhost:4173/index.html#results",
device: "mobile",
type: "custom",
output: "screenshots/results-mobile-custom.png",
width: 390,
height: 844,
waitUntil: "load",
timeout: 30000,
delay: 0,
format: "png"
});Types are exported:
import type {
RenderDevice,
RenderOptions,
RenderType,
ScreenshotFormat,
WaitUntil
} from "renderly";Exit Codes
0 screenshot saved successfully
1 invalid options, navigation failure, browser failure, or screenshot failureTroubleshooting
The screenshot is taken before app content appears
Add a delay:
npx renderly --url http://localhost:4173/index.html --device pc --type viewport --delay 1500 -o screenshots/page.pngIf your app has deterministic loaded states, prefer adding a stable anchor or visible loaded section in the app rather than relying only on time.
networkidle times out
Use the default load mode:
npx renderly --url https://spacex.com/ --device mobile --type full-page -o out.pngModern sites often keep network activity open.
Hash anchor lands slightly lower than expected
If a fixed header covers the section, set scroll-margin-top in the website CSS:
#results {
scroll-margin-top: 96px;
}Images are missing
Check that the images load in a normal browser first. If they appear after delayed scripts or animations, add --delay.
npx renderly --url http://localhost:4173/index.html#results --device pc --type viewport --delay 2000 -o screenshots/results.pngFull-page screenshot is very tall
That is expected. Full-page mode captures the whole document.
Use viewport or custom if you only need one screen.
npx renderly is not using local changes during development
After changing TypeScript source, rebuild:
npm run buildFor local development, this command avoids fetching a remote package:
npx --no-install renderly --url http://localhost:4173/index.html --device pc --type viewport -o out.pngDevelopment
Install dependencies:
npm installTypecheck:
npm run typecheckBuild:
npm run buildRun from source:
npm run dev -- --url http://localhost:4173/index.html --device pc --type viewport -o out.pngRun built CLI:
node dist/cli.js --url http://localhost:4173/index.html --device pc --type viewport -o out.png