Set Cypress’s application viewport before the run:
CYPRESS_VIEWPORT_WIDTH=1280 CYPRESS_VIEWPORT_HEIGHT=800 cypress run
Cypress maps those variables to viewportWidth and viewportHeight. They override the same values in cypress.config.js or cypress.config.ts, so you can produce desktop, tablet, and mobile screenshots in CI without editing source files. This changes the page’s layout viewport; it is different from cropping the saved image, adding padding around an element, scaling a capture, or enlarging the browser display.
Use environment variables for a run-wide viewport
For a Unix-like shell, put the variables immediately before the Cypress command:
CYPRESS_VIEWPORT_WIDTH=1280 CYPRESS_VIEWPORT_HEIGHT=800 npx cypress run
The values are pixels. Cypress applies them to every test unless a test or suite changes the viewport later. The command-line variables take precedence over viewportWidth and viewportHeight in your Cypress configuration, as documented in the Cypress configuration reference.
Recommended Free Tools
#1 Best Overall
Persist the default in configuration
Use configuration when a size should be the project’s normal behavior:
import { defineConfig } from 'cypress'
export default defineConfig({
viewportWidth: 1280,
viewportHeight: 800,
})
Environment variables are useful when the same test suite must run at several sizes. For example, the configuration can remain at 1280 × 800 while a mobile CI job runs with CYPRESS_VIEWPORT_WIDTH=390 and CYPRESS_VIEWPORT_HEIGHT=844.
Check the effective values
If a screenshot looks wrong, log the values that Cypress is using from inside a test:
cy.then(() => {
cy.log(`viewport: ${Cypress.config('viewportWidth')} × ${Cypress.config('viewportHeight')}`)
})
This is diagnostic logging only. In Cypress 16 and later, changing these values with Cypress.config() while a test is executing is no longer supported. Use cy.viewport() for a runtime change instead.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Choose the right resize method
“Resize the screenshot” can describe four different operations. Select the one that matches the result you need.
| Method | When it takes effect | Changes page layout? | Changes captured rectangle? | Changes browser display? | Best use |
|---|---|---|---|---|---|
CYPRESS_VIEWPORT_WIDTH/HEIGHT |
Before the run | Yes | Indirectly | No | Run-wide CI profiles |
viewportWidth/viewportHeight in config |
Project startup | Yes | Indirectly | No | A stable project default |
cy.viewport() |
During a test | Yes | Indirectly | No | Different sizes in one run |
clip in cy.screenshot() |
At capture time | No | Yes | No | An exact crop |
Element padding |
At element capture | No | Yes, around the element | No | Context around a component |
scale |
At capture time | No | Fits content into available area | No | Fitting a large capture |
before:browser:launch |
Browser startup | No | No | Yes | Removing a display-size bottleneck |
The APIs and distinctions above are described in the cy.screenshot() documentation, the Cypress.Screenshot API, and the cy.viewport() documentation.
Set a viewport for one test or suite
When only part of a spec needs a different layout, keep the run default and scope the override:
Rank #2
describe('medium screen', {
viewportWidth: 400,
viewportHeight: 1000,
}, () => {
it('renders the compact layout', () => {
cy.visit('/')
cy.screenshot('compact')
})
})
Cypress restores the configured default between tests. This makes scoped settings safer for visual suites than leaving a mutable global value behind.
Change size during a test
Use cy.viewport(width, height) when the same test must exercise multiple breakpoints:
it('checks desktop and mobile navigation', () => {
cy.visit('/')
cy.viewport(1280, 800)
cy.get('[data-cy=nav]').should('be.visible')
cy.screenshot('desktop-nav')
cy.viewport(390, 844)
cy.get('[data-cy=menu-button]').click()
cy.screenshot('mobile-nav')
})
Wait for responsive transitions or content to settle before capturing. If your application uses a resize observer, give it a deterministic signal such as an element assertion rather than an arbitrary long delay.
Crop a screenshot to exact dimensions
Changing the viewport makes the application reflow. If the layout is already correct and you only need a 400 × 300 rectangle from the saved image, use clip:
cy.screenshot('header-crop', {
clip: { x: 20, y: 20, width: 400, height: 300 },
})
The coordinates describe the capture rectangle; they do not alter CSS media-query behavior. A crop outside the rendered page can produce an empty or incomplete result, so choose coordinates after the page has loaded.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Capture an element with surrounding space
cy.get('.post').screenshot('post-card', { padding: 10 })
padding expands the element image bounds. It is not equivalent to changing the viewport and does not make neighboring responsive content reflow.
Understand scale
scale: true fits a viewport or fullPage capture into the available browser area. Cypress coerces scale to true for runner captures. Scaling changes how content fits; it is not a promise of a particular output pixel size. Avoid it when exact dimensions are part of a visual-regression contract.
Rank #3
Why a larger viewport may not create a larger image
Cypress renders the application viewport inside a real browser and iframe. If the browser’s display area is smaller than the configured viewport, Cypress may scale the page to fit. Consequently, setting 1280 × 800 can still result in a file whose pixel dimensions are lower than expected.
For high-resolution output, coordinate both layers:
Free tools Windows power users keep installed
One-click scans. No signup required.
- Set
CYPRESS_VIEWPORT_WIDTHandCYPRESS_VIEWPORT_HEIGHT(or the equivalent config values). - Use the
before:browser:launchevent to provide a sufficiently large browser display. - Do not rely on
scalewhen exact pixels matter. - Inspect the dimensions reported by the screenshot callback or your image-processing step.
The launch event changes browser display dimensions; Cypress explicitly notes that it does not change viewportWidth or viewportHeight in configuration. See before:browser:launch and Cypress’s high-resolution screenshots and videos guidance.
Example launch configuration
Add the launch hook in setupNodeEvents and keep viewport settings separate:
import { defineConfig } from 'cypress'
export default defineConfig({
viewportWidth: 1280,
viewportHeight: 800,
e2e: {
setupNodeEvents(on, config) {
on('before:browser:launch', (browser, launchOptions) => {
if (browser.family === 'chromium') {
launchOptions.args.push('--window-size=1600,1200')
}
return launchOptions
})
},
},
})
The exact browser flags can vary by browser and execution environment. Treat the display size as a second constraint, not as a replacement for the Cypress viewport.
Cross-platform CI commands
Linux and macOS shells
CYPRESS_VIEWPORT_WIDTH=1440 CYPRESS_VIEWPORT_HEIGHT=900 npx cypress run
Windows Command Prompt
set CYPRESS_VIEWPORT_WIDTH=1440
set CYPRESS_VIEWPORT_HEIGHT=900
npx cypress run
Windows PowerShell
$env:CYPRESS_VIEWPORT_WIDTH = '1440'
$env:CYPRESS_VIEWPORT_HEIGHT = '900'
npx cypress run
npm scripts with a portable setter
For a team that runs Windows and Unix-like systems, use your CI provider’s environment-variable fields or a cross-platform environment setter. The important part is that the process launching Cypress receives the names CYPRESS_VIEWPORT_WIDTH and CYPRESS_VIEWPORT_HEIGHT; Cypress then maps them to the configuration keys.
Keep separate CI jobs or matrix entries for each target size. Name artifacts with the dimensions, such as checkout-390x844 and checkout-1440x900, so a failure cannot silently overwrite another viewport’s image.
Rank #4
Make visual comparisons deterministic
Cypress recommends an explicit, consistent viewport for visual testing. A stable size is necessary but not sufficient: operating-system differences, browser versions, display scaling, and installed fonts can change rendered pixels even when application code is unchanged. Pin the browser and OS image where possible, install the same fonts, and keep screenshot commands at a consistent point in the loading sequence.
- Set the viewport through CI variables or checked-in configuration.
- Wait for the application’s key element and fonts before capturing.
- Use identical browser versions for baseline and comparison runs.
- Avoid animations, blinking carets, random data, and time-dependent content.
- Keep the browser display large enough that Cypress does not fit the page down.
- Record the effective viewport and output dimensions with failed artifacts.
For additional visual-testing context, see Cypress’s visual testing guidance.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting viewport and screenshot size
The environment variable appears to be ignored
Confirm spelling and capitalization: CYPRESS_VIEWPORT_WIDTH and CYPRESS_VIEWPORT_HEIGHT. Verify that the variables are set in the same process that starts Cypress, not only in a separate shell step. Log the effective configuration, and check that a later cy.viewport() call or suite-level setting is not replacing it.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsThe page has the wrong responsive layout
Check whether the test calls cy.viewport() after cy.visit(). Set the desired size before the page-dependent assertions, then revisit the page if your application only evaluates breakpoints during initial load. Also check for a device preset or helper that changes the viewport.
The image is cropped but the layout is unchanged
That is expected when using clip. Replace the crop with an environment variable, configuration value, or cy.viewport() if the page itself must reflow.
The configured size is large but the file is small
The browser display is probably constraining the render, or scale is fitting the capture. Increase the launch display size, disable scaling when exact pixels are required, and inspect the callback-reported dimensions.
A runtime Cypress.config() assignment fails
In Cypress 16 and later, viewportWidth and viewportHeight cannot be set with Cypress.config() while a test is executing. Replace that assignment with cy.viewport(), or move the value to suite/test configuration.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated 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 matchVisual diffs occur only in CI
Compare browser and OS versions, installed fonts, device-pixel ratio, timezone, and display scaling. Ensure the same environment variables are present in every job and that parallel workers are not mixing baselines from different dimensions.
Or skip the browser setup
If your goal is a clean image or PDF of a URL rather than an end-to-end assertion, ScreenshotNeo provides a single HTTP request. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Use the ScreenshotNeo API documentation for all options, including viewport presets, full-page lazy-image loading, CSS-selector element capture, dark mode, retina scale, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture, usage data, and the OpenAPI specification.
cURL
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 Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan. Create a free ScreenshotNeo account to try it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently Asked Questions
What is Cypress’s documented default viewport?
The Cypress 2026 documentation lists a default viewport of 1000 × 660 pixels before a test changes it.
Can I use different environment-variable sizes in one Cypress command?
A process has one effective pair for a run. Use separate CI matrix jobs, or call cy.viewport() and suite/test configuration for multiple sizes within a run.
How can I verify the actual PNG dimensions?
Use the screenshot callback or inspect the generated file with an image tool; the configured application viewport and the final file dimensions can differ when browser display fitting or scaling is involved.
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.

