Full-page screenshots at multiple viewports β CLI and Web UI
Powered by Playwright
π Plugin's Homepage β’ Features β’ Quick Start β’ CLI Usage β’ Web UI β’ Configuration β’ Build
πΈ Full-page Β π― DesktopΒ·TabletΒ·Mobile Β π Web UI Β π₯οΈ CLI Β π PDF Β πΌοΈ WebP/AVIF Β β‘ Live progress Β βοΈ Auto-setup Β π Adjustable delays Β π« Popup blocking Β π Hide elements Β β³ Wait for selector Β π« Domain blocklist Β π Concurrency Β π REST API Β π·οΈ Custom naming Β π¦ Standalone binary Β π Auto-stop Β π§Ή Header whitespace fix
Capture, archive, and automate screenshots of websites in PNG, WebP, AVIF, and PDF formats β with advanced controls for delays, concurrency, and DOM manipulation. Perfect for portfolio archiving, legal records, and automation workflows.
![]() |
![]() |
CyberSnapper is a powerful tool for capturing, archiving, and automating website screenshots. Originally built as an internal tool at CYBER BRAND for portfolio archiving, it has evolved into a full-featured website archiver with advanced controls for precision capture.
Use it for:
- Portfolio archiving (client websites, case studies).
- Legal records (save websites as PDFs for compliance).
- Automation (integrate with Zapier, n8n, or CI/CD pipelines).
- Custom screenshots (hide elements, wait for selectors, adjust delays).
./dist/CyberSnapper # opens web UI in browser
./dist/CyberSnapper urls.txt # CLI mode| Platform | File |
|---|---|
| Windows | run.bat |
| Linux / macOS | run.sh |
Auto-installs npm dependencies on first run, then opens the web UI.
If Node.js is not installed, the launcher will detect it and either:
- Windows (10 1809+ / 11): Prompt to install Node.js automatically via
winget- Linux / macOS: Show the exact install command for your package manager
node capture.js # uses urls/urls.txt
node capture.js urls.txt # URLs from a file
node capture.js https://example.com ... # inline URLsnode capture.js [urls.txt | url1 url2 ...]
node capture.js --stop # stop a running web-UI server
The CLI loads settings from config.json and processes all URLs:
- Delays:
initialDelay,scrollDelay,finalDelay(seconds). - Concurrency: Number of websites to capture in parallel (worker-pool pattern, one Playwright context per worker).
- Formats: Output formats (PNG, WebP, AVIF, PDF).
- Advanced:
hideSelectors,waitForSelector,blockPopups,blocklist.
When launched without arguments, CyberSnapper starts a web UI server. It stops automatically when any of the following happens:
- you click βΉ Stop in the UI header,
- you close the browser tab (the UI sends a
/shutdownonbeforeunload), - the server has seen no activity for 15 minutes (auto-stop). A toast appears in the last 60 seconds with a Keep alive button.
You can also stop a forgotten instance from the terminal:
node capture.js --stop # or: node src/index.js --stopThis reads the PID file (next to config.json, named .cybersnapper.pid)
and sends SIGTERM (escalating to SIGKILL after 3s). Starting a second
server while one is already running will be refused.
Capture screenshots programmatically:
curl "http://localhost:3000/api/screenshot?url=https://example.com&token=YOUR_TOKEN"Parameters:
url: Target website (required).format: Output format (png,webp,avif,pdf).token: API token fromconfig.json(required).
The response is an SSE stream of capture events (url-start, viewport-start,
viewport-done, url-done, done), one data: {...} line per event.
When launched without arguments, CyberSnapper starts a local web server and opens your browser.
- Paste URLs (one per line)
- Select viewport presets
- Hit πΈ Snap!
- Watch live progress β viewport frames populate with thumbnails grouped under each URL
| Feature | Description |
|---|---|
| π¨ Theme | Dark by default; toggle in header persists choice to config.json (theme: "dark" | "light") |
| π Presets | Add, remove, or toggle viewport sizes on the fly |
| β±οΈ Delays | Adjust initial, scroll, and final delays for optimal loading |
| π« Popup blocking | Toggle to block popups/modals (checkbox in Advanced panel) |
| π« Domain blocklist | URL substrings to block (one per line, merged with built-in blocklist) |
| π§Ή Header whitespace fix | Automatically strips leading white space from full-page PNGs (toggle in Advanced panel) |
| π Hide elements | Hide specific elements before capturing (CSS selectors) |
| β³ Wait for selector | Wait for a specific element before capturing |
| π Concurrency | Capture multiple websites in parallel |
| πΌοΈ Formats | Choose output formats (PNG, WebP, AVIF, PDF) |
| π REST API | Integrate with Zapier, n8n, or CI/CD pipelines |
| π·οΈ Naming | Custom output filenames with variables ({hostname}, {preset}, {width}, {height}, {domain}, {date}, {time}, {index}) |
| πΌοΈ Viewport frames | Framed cards with viewport name label and thumbnail, grouped under each URL β click for lightbox with full-res image and styled scrollbar |
| πΌοΈ No-image placeholder | Pending frames show β icon + "NO IMAGE"; active frame has cyber glow pulse + scanning line animation |
| βοΈ Auto-setup status | On first run, a live status bar with spinner and progress bar shows Chromium install and system deps progress in real time |
| π Open folder | Reveals screenshots in your file manager |
| π Auto-stop | Server shuts down after 15 min idle (toast countdown at 60s); --stop from CLI; single-instance lock |
Edit config.json to customize presets, delays, formats, and advanced settings:
{
"presets": [
{ "name": "Desktop", "width": 1920, "height": 1080 },
{ "name": "Tablet", "width": 768, "height": 1024 },
{ "name": "Mobile", "width": 375, "height": 812 }
],
"initialDelay": 1.5,
"scrollDelay": 1.8,
"finalDelay": 1.0,
"concurrency": 1,
"formats": ["png"],
"webp": { "quality": 80 },
"avif": { "quality": 50 },
"pdf": {
"format": "A4",
"landscape": false,
"margin": "0"
},
"hideSelectors": [],
"waitForSelector": "",
"blockPopups": false,
"blocklist": [],
"stripWhitespace": true,
"apiToken": "generated_on_first_run",
"naming": {
"template": "{hostname}-{preset}"
},
"theme": "dark"
}Changes are saved automatically from the Web UI. The apiToken is generated once
on first run and preserved across saves (the Web UI saves omit it deliberately β
the server keeps the existing token on disk).
| Setting | Default | Purpose |
|---|---|---|
initialDelay |
1.5s | Wait before scrolling (above-the-fold). |
scrollDelay |
1.8s | Wait between scroll steps. |
finalDelay |
1.0s | Wait after scrolling back to top. |
concurrency |
1 | Number of websites to capture in parallel. |
- PNG: Lossless, high quality (default).
- WebP: Smaller files, good quality (quality: 1-100).
- AVIF: Even smaller files, modern format (quality: 1-100).
- PDF: For archiving/legal records (A4/Letter, portrait/landscape).
| Setting | Purpose |
|---|---|
blockPopups |
Block popups/modals (checkbox). Merges a built-in CMP/analytics domain blocklist + the user blocklist + hide-popup CSS. |
blocklist |
Custom URL substrings to block (one per line). Merged with the built-in domain list when blockPopups is enabled. |
stripWhitespace |
Automatically strips leading blank rows from full-page PNG screenshots via sharp post-processing (default: true). |
hideSelectors |
CSS selectors to hide before capturing. |
waitForSelector |
Wait for this selector before capturing. |
| Setting | Default | Purpose |
|---|---|---|
theme |
"dark" |
UI theme ("dark" or "light"). The Web UI toggle writes this field; browser preferences are ignored. |
- Endpoint:
GET /api/screenshot?url=...&token=... - Authentication: Requires
apiTokenfromconfig.json. - Parameters:
url: Target website.format: Output format (png,webp,avif,pdf).
- Example:
curl "http://localhost:3000/api/screenshot?url=https://example.com&token=YOUR_TOKEN"
| Variable | Example |
|---|---|
{hostname} |
example_com |
{preset} |
desktop |
{width} |
1920 |
{height} |
1080 |
{domain} |
example.com |
{date} |
2026-07-04 |
{time} |
14-30-00 |
{index} |
01 |
npm run buildProduces dist/CyberSnapper (~90 MB, includes Playwright). The binary works on the platform it was built on.
CyberSnapper/
βββ capture.js CLI entry point (thin wrapper around src/cli.js)
βββ run.sh / run.bat Clickable launchers (web UI)
βββ build.js Standalone binary build script
βββ config.json Viewport presets & naming config
βββ src/
β βββ index.js Binary entry (CLI when args given, else web server)
β βββ cli.js CLI output logic + URL loading
β βββ config.js Config loader/saver (single normalize() helper)
β βββ naming.js Filename template engine
β βββ capture/
β β βββ index.js capture() orchestrator (concurrency, viewport loop)
β β βββ browser.js Chromium launcher (+ auto-install on first run)
β β βββ popupBlocker.js Blocked domains + hide-popup CSS
β β βββ scrolling.js Full-page scroll + waitForSelector
β β βββ formats.js PNG/WebP/AVIF/PDF writers (sharp)
β βββ server/
β βββ index.js HTTP server factory + UI asset bundling + inactivity watchdog + single-instance lock
β βββ routes.js Route handlers (/capture, /api/screenshot, /keepalive, β¦)
β βββ pid.js PID file + --stop helper
βββ ui/
β βββ index.html UI structure (CSS + JS inlined at server start)
β βββ styles.css Refined cyberpunk theme (dark/light)
β βββ app.js Client logic (SSE progress, gallery, config sync)
βββ urls/
β βββ urls.txt Default URL list
β βββ example.txt Example list
βββ screenshots/ Output directory (gitignored)
βββ dist/ Built binaries (gitignored)
- Node.js 18+ (when running from source)
- npm (for
npm install/npm run build) - The standalone binary has no dependencies beyond the bundled
node_modules/.
If you don't have Node.js installed, run the appropriate launcher (run.bat on Windows, run.sh on Linux/macOS) β it will detect the missing dependency and guide you through installation.
On Windows 10 (1809+) and Windows 11, run.bat can install Node.js automatically using the built-in winget package manager. It will prompt you with:
Install Node.js LTS now? (Y/N):
Press Y to install silently (a UAC prompt may appear). After installation, the launcher continues automatically.
If winget is unavailable (older Windows), you'll be directed to nodejs.org with step-by-step instructions.
The launcher detects your package manager and shows the appropriate command:
| Distribution | Command |
|---|---|
| Debian / Ubuntu | sudo apt update && sudo apt install nodejs npm |
| Fedora | sudo dnf install nodejs npm |
| Arch Linux | sudo pacman -S nodejs npm |
| Alpine | apk add nodejs npm |
Note: On older Debian/Ubuntu (< 20.04 / < 11), the
nodejspackage installs the binary asnodejs. Ifnodeis not found after install, create a symlink:sudo ln -s /usr/bin/nodejs /usr/bin/node
If you have Homebrew installed:
brew install nodeOtherwise, download the macOS installer from nodejs.org.
nvm lets you manage multiple Node.js versions without sudo:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --ltsISC

