Open source JavaScript npm

getViewport

Define your breakpoints once in JavaScript. getViewport generates the CSS, reads back the active state via a single computed style call, and fires resize callbacks with no polling.

Every approach forces a trade-off.

Responsive JavaScript logic is a recurring pain point. window.innerWidth checks scatter magic numbers everywhere. matchMedia() listeners require a separate handler per breakpoint. Importing SCSS variables into JS tightly couples your build. Polling with a resize observer still means defining breakpoints twice.

getViewport takes a different approach: pass a plain JS object once, and it auto-generates the @media rules, injects them at runtime, and reads the active breakpoint back via getComputedStyle. One source of truth, no duplication, no polling.

Core behavior

Define once. React anywhere.

CSS custom property bridge

Breakpoints are written as @media rules that set --viewport on :root. JavaScript reads back the current state with a single getComputedStyle call instead of duplicating logic in both languages.

Instant + debounced updates

On resize, internal state updates immediately so the UI reacts fast, then settles after 100 ms. Both immediate accuracy and stable final values, without writing your own debounce.

Bootstrap-compatible defaults

Ships with standard Bootstrap 5 breakpoints (xs through xxl) out of the box. Pass any custom object to override with Tailwind, Material, or your own system.

npm or CDN, your choice.

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 -->

One CSS variable, one JS call.

When you call new getViewport(), it generates one @media rule per breakpoint and injects them into a <style> tag. Each rule sets the custom property encoding the current breakpoint name and index.

@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'; } }

CSS cascade ensures the variable always reflects the current breakpoint. A dual-source verification step cross-checks against window.innerWidth for edge cases during rapid resizes.

Nine focused methods.

Method Returns Description
getBreakpoint()'md'Current breakpoint name
getBreakpointValue()3Numeric index (1-based, smallest to largest)
isMobile()booleanValue 2 or lower (xs, sm)
isTablet()booleanValue exactly 3 (md)
isDesktop()booleanValue above 3 (lg and wider)
getWidth()1280Current window.innerWidth in px
getHeight()800Current window.innerHeight in px
getDimensions(){width, height}Both dimensions as an object
getBreakpoints(){xs: 0, …}Copy of active breakpoint definitions

Common patterns.

Basic usage

const viewport = new getViewport();

console.log(viewport.getBreakpoint());      // 'lg'
console.log(viewport.getBreakpointValue()); // 4
console.log(viewport.isMobile());           // false
console.log(viewport.getDimensions());      // { width: 1024, height: 768 }

Resize handling

window.addEventListener('resize', () => {
  if (viewport.isMobile()) {
    collapseNavigation();
  } else {
    expandNavigation();
  }
});

Custom Tailwind-style breakpoints

const viewport = new getViewport({
  sm:   640,
  md:   768,
  lg:  1024,
  xl:  1280,
  '2xl': 1536,
});

Stop duplicating your breakpoints.

MIT licensed. Source, issues, and pull requests welcome on GitHub.

Related paths.