Find the exact viewport width where a website breaks.
WIDTHSCAN is a local-first responsive QA CLI. It scans a local or deployed URL across a configurable width range, narrows deterministic failures to exact inclusive viewport-width ranges, and writes all results to your machine.
The v0.1.0 detector set is intentionally focused:
HORIZONTAL_OVERFLOWfinds reachable document-level horizontal overflow.CLIPPED_TEXTfinds visible meaningful text clipped by its own container.
Each scan generates machine-readable scan-results.json and a standalone
index.html report. Failure ranges include measurements, likely offenders,
annotated focused screenshots, and a copyable fix prompt for a developer or
coding agent. The HTML report works directly through file://; no WIDTHSCAN
server, account, cloud service, telemetry, or external API is required.
WIDTHSCAN reports evidence, not compliance. A clean scan does not prove that a site is fully responsive or accessible, and it does not establish WCAG conformance or legal compliance. Review findings in the browser and test the experience with appropriate manual, accessibility, and cross-browser methods.
- Node.js 20 or newer
- npm
- Playwright Chromium (installed separately from the npm package)
Install the repository dependencies and the Chromium browser used by the scanner:
npm install
npx playwright install chromium
npm run build
node dist/cli.js <url>For example, to scan a local development server:
node dist/cli.js http://localhost:5173After widthscan is published to npm, install the CLI globally and install the
Chromium browser binary required by Playwright:
npm install -g widthscan
npx playwright install chromium
widthscan <url>For example:
widthscan https://example.com --min 320 --max 1920 --out widthscan-reportThe package can also be run without a global WIDTHSCAN installation after it is published. The Playwright browser binary is still a separate prerequisite:
npx playwright install chromium
npx widthscan <url>On Linux, Chromium may also require system packages. Playwright can install them together with the browser when your environment permits it:
npx playwright install --with-deps chromiumThe repository workflow uses node dist/cli.js; the installed and npx
workflows expose the same widthscan executable and options.
The default output directory is widthscan-report. It contains:
index.html— the standalone human-readable report;scan-results.json— complete machine-readable evidence;screenshots/— annotated evidence images for failure ranges.
Open the report with the platform command for your shell:
# Windows PowerShell
Start-Process .\widthscan-report\index.html# macOS
open ./widthscan-report/index.html
# Linux
xdg-open ./widthscan-report/index.htmlUsage:
widthscan <url> [options]
Options:
--min <px> Minimum width (default: 320)
--max <px> Maximum width (default: 1440)
--step <px> Coarse sweep step (default: 16)
--height <px> Viewport height (default: 900)
--navigation-timeout <ms>
DOMContentLoaded timeout (default: 30000)
--settle <ms> Wait after each resize (default: 60)
--tolerance <px> Ignore overflow up to this amount (default: 1)
--ignore <css> Ignore a selector; can be repeated
--out <path> Output directory (default: widthscan-report)
--help Show help
For example, using the installed package:
widthscan https://example.com \
--min 320 \
--max 1920 \
--step 16 \
--height 900 \
--settle 100 \
--out widthscan-report--min and --max define the requested scan interval. --step controls the
coarse sweep; WIDTHSCAN then refines observed pass/fail transitions to exact
pixel boundaries. A coarse sweep can miss a failure narrower than the step if
no sampled width lands inside it, so use a smaller step when investigating a
narrow responsive transition. --height sets the browser viewport height, and
--settle gives responsive layout and animation state time to stabilize after
each resize.
--out selects the report directory. WIDTHSCAN writes the current report and
evidence there; use a fresh output path when preserving an earlier run or when
you do not want older screenshot files beside the new evidence.
Ranges are inclusive. A reported 412–427px issue was observed at every
refined width from 412px through 427px; WIDTHSCAN also observed passing widths
immediately outside both boundaries.
A range touching the configured scan boundary has an unknown outer boundary:
≤320–338pxmeans the issue was present at the 320px minimum and ended at 338px. WIDTHSCAN did not inspect 319px.641–≥1920pxmeans the issue began at 641px and remained present at the 1920px maximum. WIDTHSCAN did not inspect 1921px.320–1920px (scan-bounded)means it was present across the entire configured interval; both outer boundaries remain unknown.
Expand --min or --max to discover an unknown outer boundary. WIDTHSCAN never
claims that an unscanned adjacent width passes.
The report coverage summary distinguishes detector types from issue ranges.
Each detector receives a compact status badge: passed when it produced no
findings, or the number of independent issue ranges otherwise. Passed detectors
do not create empty issue cards.
Some interfaces deliberately place content outside a component's visible area. Examples include decorative animation fields, continuously moving marquee tracks, and text that is intentionally clipped and revealed during an interaction. These can be valid design behavior, but they should be ignored only after manual verification confirms that the content is contained and not the cause of a real layout failure.
Use the narrowest stable selector that identifies the intentional component:
widthscan https://example.com \
--ignore ".ambient-stardust" \
--ignore ".logo-marquee__track" \
--ignore "[data-reveal-text]"--ignore may be repeated. An ignored element or matching ancestor is excluded
from findings and evidence for both current detectors. Prefer a component-level
class or explicit data attribute over a broad selector such as main, section,
or *; broad ignores can hide unrelated defects. Repeat the scan after adding
an ignore and verify that any unrelated failure range remains visible.
npm run build
npm test
npm run test:e2eThe controlled E2E fixture verifies exact 412–427px horizontal-overflow and
684–719px clipped-text ranges, intentional suppression, boundary semantics,
evidence cleanup, and standalone report generation.
See field-validation notes for time-specific browser observations from real pages, the product brief for MVP scope, and the architecture for scanner contracts.
WIDTHSCAN is distributed under the existing MIT License.