Tiny zero‑config VisualViewport-first store for accurate visible viewport size in CSS pixels. Detects virtual keyboard, stabilizes resize/scroll jitter, and is SSR-safe across frameworks.
npm install viewport-truthbash
npm i viewport-truth
or: yarn add viewport-truth
or: pnpm add viewport-truth
`
Quick Start
Minimal flow: import → create → subscribe → get { width, height, isKeyboardOpen, isStable }.
`js
import { createViewportTruth } from "viewport-truth/vanilla";
const vt = createViewportTruth();
const unsub = vt.subscribe((v) => {
if (!v) return;
console.log(
visible=${v.width}x${v.height} keyboard=${v.isKeyboardOpen} stable=${v.isStable}
);
});
// later:
// unsub();
// vt.destroy();
`
Wow example (keyboard eats UI… and you can see it)
A tiny bottom bar that stays visible and shows exactly how much viewport you lost.
> Run it in a real page (Vite/Parcel/Next) — the snippet won’t execute inside README.
> On mobile: scroll a bit (URL bar), then focus the input (keyboard).
`html
placeholder="Focus me to open keyboard"
style="width:100%;padding:12px;font-size:16px;box-sizing:border-box"
/>
Tip: scroll a bit (URL bar animates), then focus the input.
`
Features
A few concrete, technical reasons it behaves well on mobile:
- Tiny: ~< 2 KB min+gzip (check the Bundlephobia badge).
- Fast updates: emits at most 1 update per animation frame (rAF throttling).
- Zero runtime deps: 0 dependencies at runtime (tree-shakeable ESM).
- Stable signal: isStable flips after 150ms (default) without geometry changes.
---
API (short)
Core snapshot fields you’ll typically use:
- width, height — visible viewport size (CSS px)
- layoutWidth, layoutHeight — layout viewport (basis for keyboard detection)
- isKeyboardOpen — geometry-based keyboard inference
- isStable — “animations settled” signal for UI decisions
Vanilla store:
- createViewportTruth() from viewport-truth/vanilla → creates a store with subscribe() and destroy()
Framework adapters:
- React: useViewportTruth from viewport-truth/react
- Vue: useViewportTruth from viewport-truth/vue
- Svelte: viewportTruth from viewport-truth/svelte
- Solid: createViewportTruth from viewport-truth/solid
- Angular: ViewportTruthDirective from viewport-truth/angular
Full types and signatures: see dist/*.d.ts (or TypeScript IntelliSense).
Adapter Docs: React •
Vue •
Svelte •
Solid •
Angular
> Tip: Open links in a new tab with Ctrl+Click (Windows/Linux) or Cmd+Click (macOS).
$3
FAQ •
Common pitfalls •
Smoke test (clean environment) •
Versioning policy
Support the project
> “We ate the Geometry Hell for you: jumping 100vh, jittery resize`, modals under the keyboard.