Responsive breakpoint detection for JavaScript — without magic numbers or resize polling. Define breakpoints once in JS; GetViewport injects the CSS and keeps your code in sync automatically.
Responsive JavaScript logic is a recurring pain point. Every common approach forces a trade-off between brittle code and maintenance overhead.
| Approach | Problem |
|---|---|
window.innerWidth checks |
Magic numbers scattered across your codebase |
| CSS pseudo-element hacks | Fragile, non-standard, hard to maintain |
| Importing SCSS breakpoints into JS | Requires a build step; tightly couples CSS and JS |
matchMedia() listeners |
Verbose boilerplate; a separate listener per breakpoint |
| Resize observer polling | Overhead; still requires defining breakpoints twice |
GetViewport's approach
Define breakpoints once as a JS object.
GetViewport auto-generates the CSS, injects it at runtime, and reads the active breakpoint back
via a single getComputedStyle call — no duplication, no polling.
npm / yarn
npm install get-viewport
// CommonJS
const GetViewport = require('get-viewport');
// ESM
import GetViewport from 'get-viewport';
CDN
<script src="https://unpkg.com/get-viewport/getViewport.js"></script>
<!-- window.GetViewport is now available -->
When you call new GetViewport(), it generates one @media rule per
breakpoint and injects them into a <style> tag. Each rule sets a CSS custom
property on :root encoding the current breakpoint name and its index.
Auto-injected CSS (default breakpoints)
@media (min-width: 0px) { :root { --viewport: 'xs,1'; } }
@media (min-width: 576px) { :root { --viewport: 'sm,2'; } }
@media (min-width: 768px) { :root { --viewport: 'md,3'; } }
@media (min-width: 992px) { :root { --viewport: 'lg,4'; } }
@media (min-width: 1200px) { :root { --viewport: 'xl,5'; } }
@media (min-width: 1400px) { :root { --viewport: 'xxl,6'; } }
Because CSS cascade applies the last matching rule, the variable always reflects the current breakpoint. JavaScript reads it with a single call:
getComputedStyle(document.documentElement).getPropertyValue('--viewport')
A dual-source verification step cross-checks the CSS variable against direct
window.innerWidth comparisons to handle edge cases during rapid resizes or CSSOM
staleness.
Pass a plain JS object and GetViewport handles everything — no separate SCSS map, no repeated
matchMedia strings. Change a breakpoint in one place and both CSS and JS update
automatically.
On resize, the internal state updates immediately so the UI reacts fast, then settles again after 100 ms. Both immediate accuracy and stable final values — without writing your own debounce logic.
Ships with the standard Bootstrap 5 breakpoints (xs → xxl) out of the
box. Pass any custom object — Tailwind-style, Material, or your own system — to override.
Browser <script> tag, CommonJS require(), AMD
define(), or ESM import via a bundler — all supported with the same
zero-config UMD wrapper.
Constructor
const viewport = new GetViewport(customBreakpoints?);
| Method | Returns | Description |
|---|---|---|
getBreakpoint() |
'md' |
Current breakpoint name |
getBreakpointValue() |
3 |
Numeric index (1-based, smallest → largest) |
isMobile() |
boolean |
Value ≤ 2 (xs, sm) |
isTablet() |
boolean |
Value === 3 (md) |
isDesktop() |
boolean |
Value > 3 (lg and above) |
getWidth() |
1280 |
Current window.innerWidth in px |
getHeight() |
800 |
Current window.innerHeight in px |
getDimensions() |
{width, height} |
Both dimensions as an object |
getBreakpoints() |
{xs: 0, …} |
Copy of the active breakpoint definitions |
Basic usage
const viewport = new GetViewport();
console.log(viewport.getBreakpoint()); // 'lg'
console.log(viewport.getBreakpointValue()); // 4
console.log(viewport.isMobile()); // false
console.log(viewport.isDesktop()); // true
console.log(viewport.getDimensions()); // { width: 1024, height: 768 }
Respond to resize events
const viewport = new GetViewport();
window.addEventListener('resize', () => {
if (viewport.isMobile()) {
collapseNavigation();
} else {
expandNavigation();
}
});
Range guards with
getBreakpointValue()
const bp = viewport.getBreakpointValue();
if (bp >= 2 && bp <= 3) {
// sm through md — tablets and large phones
}
if (bp >= 4) {
// lg and above — load heavier desktop features
import('./desktop-charts.js').then(m => m.init());
}
Custom Tailwind-style breakpoints
const viewport = new GetViewport({
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
'2xl': 1536,
});
console.log(viewport.getBreakpoint()); // 'lg' at 1100px
GetViewport is MIT-licensed and available on npm. Source, issues, and pull requests welcome on GitHub.