npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

webrenderly

v0.1.0

Published

CLI tool for rendering website screenshots in desktop, mobile, full-page, and custom viewport modes.

Downloads

110

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.png

Install in a project:

npm install --save-dev renderly

Then run:

npx renderly --url http://localhost:4173/index.html --device mobile --type full-page -o screenshots/mobile-full.png

Renderly 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.png

CLI 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: 2

Renderly 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.png

Captures:

1920x1080

Use 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.png

Starts 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.png

Captures:

450x1000

Use 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.png

Starts 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.png

Custom 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 1600 renders as a desktop browser in an 800x1600 viewport.
  • --device mobile --type custom -w 800 -h 1600 renders as a mobile/touch browser in an 800x1600 viewport.

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.png

This is more reliable than trying to crop screenshots manually or guessing scroll offsets.

Recommended anchor practice:

  • Add stable id values for important sections such as hero, pricing, results, features, faq, and footer.
  • 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:

  1. Waits for page navigation according to --wait-until.
  2. Waits for document fonts.
  3. If the URL has a hash anchor, waits for the target to exist.
  4. For full-page screenshots, scrolls through the document to wake lazy-loaded content.
  5. 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.
  6. Waits for images to load or fail.
  7. Performs a final instant scroll to the hash target for viewport/custom captures.
  8. Waits for layout to settle.
  9. 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.png

Wait Modes

Default:

--wait-until load

Use 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.png

Recommended 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.png

For 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.png

For 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.png

Programmatic 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 failure

Troubleshooting

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.png

If 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.png

Modern 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.png

Full-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 build

For 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.png

Development

Install dependencies:

npm install

Typecheck:

npm run typecheck

Build:

npm run build

Run from source:

npm run dev -- --url http://localhost:4173/index.html --device pc --type viewport -o out.png

Run built CLI:

node dist/cli.js --url http://localhost:4173/index.html --device pc --type viewport -o out.png