mrkeyoor.com_
Sat 08 Aug 20:59 UTC
npmCLI & Toolingupdated 08 Aug 2026

window-size

window-size is a legacy CommonJS helper for reading terminal rows and columns in Node. At import time it tries `process.stdout`, then `process.stderr`, `COLUMNS` and `ROWS` environment variables, and an old `tty.getWindowSize` fallback. A successful result contains `width`, `height`, and an undocumented `type` describing the source; helper methods can query again or synchronously call `tput` and a Windows command. It also installs a small `window-size` executable.

Verdict

Do not add `window-size` to a new Node CLI; the built-in TTY stream properties are enough for most programs, and `term-size` is a better fallback package. Keep it only for legacy compatibility, with explicit guards for an undefined export.

API stability3/5The import-time object, `.get()`, `.env()`, `.tty()`, `.tput()`, and `.win()` shape has been frozen since 1.1.1, so legacy consumers see little churn. The unusual conditional export means the entire method surface changes with runtime environment, and two helpers depend on obsolete or platform-specific external APIs.
Docs3/5The README explains the main result, live query, resize event, environment, TTY, Windows, tput, direct utils import, and the possibility of an undefined result. It omits the returned `type`, CLI crash behavior, synchronous blocking cost, conditional disappearance of helpers, and the fact that `.win()` reads display resolution rather than console size.
Maintenance1/5npm lists 1.1.1 from July 2018 as the latest release. GitHub reports a repository push in August 2024 and the project is not archived or deprecated, but no package update addressed modern Node stream APIs, WMIC obsolescence, conditional exports, types, or the non-TTY CLI crash, so practical maintenance is dormant.
Ecosystem3/5The package recorded 4,188,972 downloads for the measured week, showing a large transitive footprint in older CLI stacks, but the repository has only 85 stars and the API has no integrations or extension points. Current Node provides the primary data directly, and newer terminal-size packages cover fallbacks without this exact export trap.

Use it if

  • You maintain an existing CommonJS CLI whose behavior already depends on this package's fallback order
  • You must support very old Node versions where `process.stdout.columns` and `rows` were inconsistent
  • Your controlled environment supplies numeric `COLUMNS` and `ROWS` when stdout is not a TTY
  • You need to preserve output compatibility with a transitive tool that expects `{ width, height, type }`
Skip it if

Setup reality

`npm install window-size` adds a CommonJS module, a `window-size` executable, and two runtime dependencies. There are no native addons, peer dependencies, credentials, or config files. Import behavior is the main trap: the module measures once immediately and exports either the resulting plain object or `undefined`. It attaches `.get`, `.env`, `.tty`, `.tput`, and `.win` only when that first measurement succeeds. Therefore `require('window-size').get()` is unsafe in exactly the environments where a fallback helper might be needed. Requiring `window-size/utils` avoids that conditional method export and exposes the functions directly. The default query checks stdout before stderr, then accepts numeric `COLUMNS` and `ROWS`, then calls an old `tty.getWindowSize` API if present. The returned object also includes `type`, although the README's primary shape omits it. Resize handling is not automatic; listen on `process.stdout` and call `.get()` again, and remember the README warns that some platforms report only the initial dimensions. `.tput()` blocks the event loop with `execSync('tput cols && tput lines')`, depends on a Unix command and a meaningful terminal database, swallows all failures, and may write command errors to stderr. `.win()` also blocks, only runs when `os.release()` begins with `10`, invokes WMIC, and actually reads video-controller resolution rather than console geometry. The executable does not guard the undefined export, so it is unsuitable for pipes and CI unless size environment variables are guaranteed. No API observes `SIGWINCH` independently, distinguishes pixels from character cells, supplies defaults, or handles browser windows. For current Node, a small local helper that checks `stdout.isTTY`, `columns`, and `rows` is clearer and safer.

Patterns

Read the import-time terminal sizeread-initial-size

const size = require('window-size');

if (size) {
  console.log(size.width, size.height, size.type);
} else {
  console.log('Terminal size unavailable');
}

The main export is `undefined` when no method succeeds. The `type` field identifies `stdout`, `stderr`, `process.env`, or `tty`.

Query dimensions againrefresh-current-size

const size = require('window-size');

const current = size?.get();
if (current) {
  renderAtWidth(current.width);
}

`.get` only exists when the initial import found a size, so optional access is required in pipes and non-TTY environments.

Update layout after a resizehandle-terminal-resize

const size = require('window-size');

if (size && process.stdout.isTTY) {
  process.stdout.on('resize', () => {
    const current = size.get();
    if (current) redraw(current.width, current.height);
  });
}

The package does not subscribe for you, and its README warns that some platforms expose only the initial terminal size.

Read COLUMNS and ROWS directlyuse-environment-size

const utils = require('window-size/utils');

const environmentSize = utils.env();
if (environmentSize) {
  console.log(environmentSize.width, environmentSize.height);
}

Both values must pass the package's numeric check. This is useful in controlled CI only when you set both variables yourself.

Access helpers when the main export is undefinedaccess-utils-fallback

const size = require('window-size');
const utils = require('window-size/utils');

const current = size || utils.env() || utils.tput();

Direct utils import is necessary because helper methods are attached only after the default import succeeds. `tput()` is synchronous and platform-dependent.

Test with a supplied stream shapequery-custom-stream

const utils = require('window-size/utils');

const size = utils.get({
  stdout: { columns: 100, rows: 30 },
  stderr: null,
});

console.log(size);

The implementation checks real `process.stdout` before the supplied option, so this is not true dependency injection while normal process streams report dimensions.

Use the Unix tput fallback explicitlyquery-with-tput

const { tput } = require('window-size/utils');

const size = tput();
if (size) console.log(`${size.width}x${size.height}`);

This blocks with `execSync`, requires `tput`, may send command errors to stderr, and silently returns undefined when the command fails.

Provide deterministic dimensions in CIsupply-ci-dimensions

// shell
// COLUMNS=120 ROWS=40 node report.js

const size = require('window-size');
const width = size?.width ?? 80;

Environment values are considered only after stdout and stderr. Use an application default as the final fallback.

Read dimensions with current Node insteadavoid-package-modern-node

function terminalSize(stream = process.stdout) {
  if (!stream.isTTY) return undefined;
  return {
    width: stream.columns,
    height: stream.rows,
  };
}

For current Node this local helper is usually preferable: no import-time snapshot, dependencies, obsolete TTY fallback, or misleading Windows screen query.

Choose a bounded text widthwrap-text-safely

const size = require('window-size');

const detected = size?.width ?? 80;
const contentWidth = Math.max(20, Math.min(detected - 4, 120));
printWrapped(message, contentWidth);

Always provide and bound a fallback because terminal columns may be missing, stale, or unreasonable in redirected and embedded environments.

Alternatives

PackageRegistryPick it when
term-sizenpmYou need a maintained terminal-size query with a current Node baseline and sensible fallbacks
terminal-sizenpmYou want a promise-based cross-platform query that can invoke platform tools when stream properties are unavailable
cli-widthnpmYou only need terminal columns for wrapping or layout and prefer a focused width API