npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opentui-responsive

v0.6.3

Published

Typed responsive breakpoints for OpenTUI.

Readme

Installation

For OpenTUI Solid applications:

bun add opentui-responsive @opentui/core @opentui/solid solid-js
# or
npm install opentui-responsive @opentui/core @opentui/solid solid-js

For OpenTUI React applications:

bun add opentui-responsive @opentui/react react
# or
npm install opentui-responsive @opentui/react react

Framework adapter authors can use the framework-neutral opentui-responsive/core entrypoint.

Usage

Create the responsive provider in your layout, then use its hook directly in child components:

src/layout.tsx

import { createResponsiveTui } from "opentui-responsive/solid";
import type { ParentProps } from "solid-js";

export const { ResponsiveTUI, useBreakpoint } = createResponsiveTui({
  // Required: each axis must include a 0 threshold.
  width: { narrow: 0, medium: 60, wide: 100 },
  height: { short: 0, medium: 16, tall: 28 },
});

export function Layout(props: ParentProps) {
  return <ResponsiveTUI>{props.children}</ResponsiveTUI>;
}

src/content.tsx

import { useBreakpoint } from "./layout.tsx";

export function Content() {
  const [width, height, viewport] = useBreakpoint();
  // Each accessor can be named for its local use.
  const isWideAndTall = viewport(["wide", "tall"]);
  const isMediumOrWider = width.atLeast("medium");
  const hasMediumViewport = viewport.atLeast(["medium", "medium"]);

  return (
    <box flexDirection={width.is("wide") ? "row" : "column"}>
      <text>{`${width()}/${height()}`}</text>
      <text>
        {isWideAndTall || (isMediumOrWider && hasMediumViewport) ? "Full layout" : "Compact layout"}
      </text>
    </box>
  );
}

src/app.tsx

import { Content } from "./content.tsx";
import { Layout } from "./layout.tsx";

export function App() {
  return (
    <Layout>
      <Content />
    </Layout>
  );
}

useBreakpoint() updates when the terminal crosses a configured threshold. It returns [width, height, viewport], letting each caller choose local names while keeping breakpoint names scoped to their axis. Width and height accept one breakpoint name; viewport accepts a [width, height] pair. Viewport pair comparisons return true only when both axes satisfy the relation.

const [width, height, viewport] = useBreakpoint();

width.below("medium");
viewport.atMost(["medium", "tall"]);
height.is("short");
viewport.atLeast(["medium", "medium"]);
width.above("medium");

const [sidebarWidth] = useBreakpoint();
const [, , layoutViewport] = useBreakpoint();

Measuring Local Layouts

Both framework adapters can measure a renderable after Yoga computes its local layout. In Solid:

import { useRenderableDimensions } from "opentui-responsive/solid";

export function Panel() {
  const [dimensions, ref] = useRenderableDimensions();
  const size = () => {
    const current = dimensions();
    return current ? `${current.width}x${current.height}` : "measuring";
  };

  return (
    <box flexDirection="column">
      <box ref={ref} border={true}>
        <text>Panel content</text>
      </box>
      <text>Panel size: {size()}</text>
    </box>
  );
}

In React, dimensions are returned as a value rather than a Solid accessor:

import { useRenderableDimensions } from "opentui-responsive/react";

export function Panel() {
  const [dimensions, ref] = useRenderableDimensions();

  return (
    <box flexDirection="column">
      <box ref={ref} border={true}>
        <text>Panel content</text>
      </box>
      <text>
        Panel size: {dimensions ? `${dimensions.width}x${dimensions.height}` : "measuring"}
      </text>
    </box>
  );
}

The dimensions are undefined until the current renderable completes its first layout, then update when its computed size changes. Keep the measured renderable visible and participating in layout; conditionally render its contents or a sibling fallback instead of hiding the measured renderable itself. Dimension-dependent output appears in a follow-up frame because OpenTUI reports size changes during its render pass.

The returned ref uses the renderable's additive resize event, so it does not replace onSizeChange. Compose refs manually if the same renderable also needs another ref callback. In React, keep a composed callback stable and forward the hook ref's cleanup function.

Run bun run demo or bun run demo:react from the package directory to try either example. Resize the terminal to see its layout respond.

The React adapter has the same factory, provider, hook, and inferred breakpoint types; import createResponsiveTui from opentui-responsive/react instead. Use PropsWithChildren for the layout's props.

API Reference

opentui-responsive/solid and opentui-responsive/react

| API | Description | | -------------------------------------- | ------------------------------------------------------------------------------------- | | createResponsiveTui(scales) | Validates the scales and creates a ResponsiveTUI provider and useBreakpoint hook. | | ResponsiveTUI | Tracks terminal dimensions and provides the current breakpoint accessor. | | useBreakpoint() | Reads [width, height, viewport] from the nearest generated provider. | | ResponsiveBreakpointAccessor | The readonly [width, height, viewport] accessor tuple. | | ResponsiveBreakpointAxisAccessor | Reads or compares one axis using that axis's breakpoint names. | | ResponsiveBreakpointViewportAccessor | Reads or compares the complete viewport using [width, height] pairs. | | ResponsiveTuiConfigurationError | Thrown when the supplied breakpoint scales are invalid. | | ResponsiveTuiProviderError | Thrown when the generated hook is called outside its provider. | | useRenderableDimensions() | Tracks the Yoga-computed size of the renderable assigned to its ref. | | RenderableDimensions | The measured renderable width and height in terminal cells. |

opentui-responsive/core

For implementing another framework adapter, not application setup:

| API | Description | | ------------------------------------ | -------------------------------------------------------------------------- | | createBreakpointDefinition(scales) | Validates scales and creates match and matches helpers for an adapter. | | BreakpointDefinition | The typed breakpoint matcher returned by createBreakpointDefinition. | | BreakpointScales | The width and height scale configuration. | | BreakpointMatch | The matched breakpoint name for each axis. | | BreakpointPair | An exact breakpoint pair in width-then-height order. | | BreakpointRelationMatcher | Tests one axis or an AND-combined pair against a named relation. | | ResponsiveTuiConfigurationError | Thrown when supplied breakpoint scales are invalid. |

Breakpoint Behavior

Width and height use independent sets of inclusive minimum thresholds measured in terminal cells. A threshold is selected when the dimension is greater than or equal to it: for example, a width threshold of 60 matches at width >= 60. Each axis must contain a zero threshold so every terminal size has a match. Names must be non-empty, and thresholds must be unique finite non-negative integers within their axis.

Declaration order does not affect matching. Each axis selects its highest satisfied threshold.

Relation methods compare complete tiers rather than their raw threshold values. Given width: { narrow: 0, medium: 60, wide: 100 }, width.atMost("medium") matches widths from 0 through 99.

| Method | Tier relation | | --------- | ------------- | | below | < | | atMost | <= | | is | === | | atLeast | >= | | above | > |

Width and height relation methods each accept a name from their own scale. Viewport relation methods accept [width, height] pairs and use AND semantics. Calling viewport.is(["wide", "tall"]) is equivalent to calling viewport(["wide", "tall"]). The /core relation matchers retain (viewport, axis, name) and (viewport, [width, height]) forms for adapter implementations.

Use breakpoints for discrete layout modes. Use OpenTUI's useTerminalDimensions() when viewport dimensions are sufficient, and the adapter's useRenderableDimensions() when local Yoga constraints determine the available space.

Runtime Support

The package is ESM-only and supports Bun 1.3.0 or later and Node.js 26.4.0 or later. CommonJS require() is not supported.

The /core entrypoint is pure JavaScript and does not require native FFI. The /react and /solid entrypoints inherit OpenTUI's native runtime requirements; Node.js applications using an adapter must start with node --experimental-ffi app.mjs. Use Bun 1.4.0 or later on native Windows arm64.