Screenshot Any URL in 3 Lines: Node.js and Python Quickstart
Three lines of code to take a screenshot of any URL in Node.js or Python. Install the SnapRender SDK, create a client, call capture(). That's it. No headless browser, no Chromium download, no Puppeteer config. You get a PNG, JPEG, WebP, or PDF back from a single function call, and the free tier gives you 500 screenshots per month.
Node.js: 3 Lines
npm install snaprender
const { SnapRender } = require('snaprender');
const client = new SnapRender({ apiKey: 'sk_live_...' });
const buffer = await client.capture({ url: 'https://example.com', format: 'png' });
That's a working screenshot. buffer contains the PNG image data. Write it to a file, pipe it to an HTTP response, or store it in S3.
const fs = require('fs');
fs.writeFileSync('screenshot.png', buffer);
Python: 3 Lines
pip install snaprender
from snaprender import SnapRender
client = SnapRender(api_key='sk_live_...')
image_bytes = client.capture(url='https://example.com', format='png')
Same idea. image_bytes is the raw image. Save it:
with open('screenshot.png', 'wb') as f:
f.write(image_bytes)
For Comparison: Puppeteer
Here's the same screenshot in Puppeteer:
const puppeteer = require('puppeteer'); // downloads 300MB Chromium
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'screenshot.png' });
await browser.close();
Seven lines, a 300 MB dependency, and you still need to handle:
- Browser process management (what if it crashes?)
- Memory usage (150-300 MB per browser instance)
- Cookie consent banners (manual CSS selector dismissal)
- Waiting strategies (which
waitUntiloption? Do you needwaitForSelector?) - Timeout handling
Puppeteer is a great tool when you need full browser automation. But if you just need a screenshot of a URL, it's a lot of machinery for a simple job. For a deeper look at when Puppeteer makes sense and when an API is the better choice, see our Puppeteer screenshot guide.
Setup: Under 2 Minutes
Step 1: Get a free API key at snap-render.com. No credit card required. The free tier includes 500 screenshots per month.
Step 2: Install the SDK.
# Node.js
npm install snaprender
# Python
pip install snaprender
Step 3: Paste these 3 lines into your code with your API key.
That's it. Time from "I need a screenshot feature" to "I have a working screenshot" is under 2 minutes.
Every Option You Can Add
The 3-line version captures a 1280x720 viewport as PNG. SnapRender's API supports a full set of options that you can add as parameters:
| Parameter | Type | Description |
|---|---|---|
url |
string | URL to capture |
format |
string | png, jpeg, webp, or pdf |
width |
integer | Viewport width (default: 1280) |
height |
integer | Viewport height (default: 720) |
full_page |
boolean | Capture full scrollable page (max 32,768px) |
dark_mode |
boolean | Force dark mode via prefers-color-scheme |
block_ads |
boolean | Remove ads before capture |
remove_cookie_banners |
boolean | Dismiss cookie consent popups |
device |
string | Emulate a device (e.g., iPhone 15, Pixel 7) |
hide_selectors |
string[] | CSS selectors to hide before capture |
click_selector |
string | Click an element before capture |
cache_ttl |
integer | Cache the result for N seconds (under 200ms on cache hit) |
No feature gating. Every option is available on every plan, including the free tier.
Common Recipes
Each recipe is a small addition to the base 3 lines. I'm showing Node.js, but the Python SDK takes the same parameters.
Capture as Mobile Device
const buffer = await client.capture({
url: 'https://example.com',
format: 'png',
device: 'iPhone 15'
});
The API sets the viewport, device scale factor, and user agent automatically. No manual viewport math.
Capture Full Page
const buffer = await client.capture({
url: 'https://example.com',
format: 'png',
fullPage: true
});
SnapRender captures the entire scrollable page up to 32,768 pixels tall. Lazy-loaded images are scrolled into view before capture.
Capture as PDF
const buffer = await client.capture({
url: 'https://example.com',
format: 'pdf'
});
A4 format with print backgrounds included. Good for invoices, reports, and any content where users expect a downloadable document.
Capture with Dark Mode
const buffer = await client.capture({
url: 'https://example.com',
format: 'png',
darkMode: true
});
Forces prefers-color-scheme: dark at the browser level. Any site that respects the media query will render in dark mode. Useful for generating OG images that match your app's dark theme.
Capture with Ad Blocking and Cookie Banner Removal
const buffer = await client.capture({
url: 'https://news-site.com',
format: 'png',
blockAds: true,
removeCookieBanners: true
});
Two boolean flags replace what would be dozens of lines of CSS selector maintenance in Puppeteer. Ad networks change their selectors constantly; SnapRender keeps up with that so you don't have to.
Custom Viewport with Hidden Elements
const buffer = await client.capture({
url: 'https://example.com',
format: 'png',
width: 1920,
height: 1080,
hideSelectors: ['.sticky-header', '.popup-overlay', '#chat-widget']
});
The hideSelectors parameter accepts an array of CSS selectors. Matched elements are hidden before the screenshot is taken. Good for removing sticky navigation, chat widgets, or any element that clutters the capture.
Click Before Capture
const buffer = await client.capture({
url: 'https://example.com',
format: 'png',
clickSelector: '#show-more-content'
});
SnapRender clicks the element matching the selector, waits for the page to settle, then captures. Useful for pages that hide content behind "Read more" or "Show all" buttons.
Cached Screenshots for Speed
const buffer = await client.capture({
url: 'https://example.com',
format: 'png',
cacheTtl: 3600
});
First request takes 2-5 seconds (fresh render). Subsequent requests within the TTL return in under 200ms. If you're generating link previews or thumbnails for URLs that don't change often, caching cuts your response time by 90%+.
Python: Full Recipe Example
The same patterns work in the Python SDK:
from snaprender import SnapRender
client = SnapRender(api_key='sk_live_...')
# Mobile + dark mode + no ads
image_bytes = client.capture(
url='https://example.com',
format='webp',
device='iPhone 15',
dark_mode=True,
block_ads=True,
remove_cookie_banners=True
)
with open('mobile-dark.webp', 'wb') as f:
f.write(image_bytes)
All the options compose freely. Stack device emulation with dark mode, ad blocking, and full-page capture in a single call.
No SDK? Use the Raw API
If you don't want any dependency, SnapRender's API is a single GET endpoint. Works from any language, any HTTP client, even curl:
curl "https://app.snap-render.com/v1/screenshot?url=https://example.com&format=png" \
-H "X-API-Key: sk_live_..." \
-o screenshot.png
Node.js with fetch:
const url = new URL('https://app.snap-render.com/v1/screenshot');
url.searchParams.set('url', 'https://example.com');
url.searchParams.set('format', 'png');
url.searchParams.set('full_page', 'true');
const response = await fetch(url, {
headers: { 'X-API-Key': 'sk_live_...' }
});
const buffer = Buffer.from(await response.arrayBuffer());
Python with requests:
import requests
response = requests.get(
'https://app.snap-render.com/v1/screenshot',
headers={'X-API-Key': 'sk_live_...'},
params={
'url': 'https://example.com',
'format': 'png',
'full_page': True
}
)
with open('screenshot.png', 'wb') as f:
f.write(response.content)
The SDK is a thin wrapper around this endpoint. It handles retries and response parsing, but the raw API is just as capable. For a full breakdown of how the API compares to other providers, see our screenshot API comparison.
Pricing
| Plan | Price | Screenshots/month |
|---|---|---|
| Free | $0 | 500 |
| Starter | $9 | 2,000 |
| Growth | $29 | 10,000 |
| Business | $79 | 50,000 |
| Scale | $199 | 200,000 |
Every feature is available on every plan. The free tier has no feature restrictions, no watermarks, no rate limits beyond the monthly cap. Start free, upgrade when you need more volume.
When to Use This vs. Puppeteer/Playwright
The 3-line approach is the fastest way to take a screenshot of a URL in Node.js or Python. It's the right choice when:
- Screenshots are a feature, not a test artifact
- You don't want to manage headless browser infrastructure
- You need features like ad blocking or cookie removal without writing selector scripts
- You want sub-200ms cached responses
- You're building link previews, OG images, PDF exports, or visual monitoring
If you need full browser automation (form filling, navigation flows, scraping, E2E testing), use Puppeteer or Playwright. But if the goal is "give me an image of this URL," SnapRender does it in 3 lines with zero operational overhead.
Get your free API key at snap-render.com and take your first screenshot in under 2 minutes.