JavaScript Responsive ~3 KB Zero Dependencies

GetViewport

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.

The Breakpoint Problem

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.

Installation

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

How It Works

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.

Define Breakpoints Once

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.

Instant + Debounced Updates

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.

Bootstrap-Compatible Defaults

Ships with the standard Bootstrap 5 breakpoints (xsxxl) out of the box. Pass any custom object. Tailwind-style, Material, or your own system. To override.

UMD. Works Everywhere

Browser <script> tag, CommonJS require(), AMD define(), or ESM import via a bundler. All supported with the same zero-config UMD wrapper.

API Reference

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

Usage Examples

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

Stop duplicating your breakpoints.

getViewport is MIT-licensed and available on npm. Source, issues, and pull requests welcome on GitHub.

Related