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

@uniview/tui-react

v0.0.3

Published

Render React components to the terminal

Readme

@uniview/tui-react

Render React components to a terminal with a custom reconciler — no react-dom.

Install

pnpm add @uniview/tui-react react
pnpm add -D typescript @types/react @types/node

The second line is TypeScript/TSX and process development tooling only. The runtime install remains @uniview/tui-react plus react.

Quick start

render() creates the terminal surface, starts input handling, and mounts your React tree. Everything in this example comes from the one public binding package.

import { Panel, Text, render } from "@uniview/tui-react";

const app = render(
  <Panel title="Hello" focused>
    <Text bold>from React</Text>
  </Panel>,
);

process.on("SIGINT", () => {
  app.destroy();
  process.exit(0);
});

app.destroy() restores the terminal. Call it before an intentional process exit. React cannot synchronously unmount while it is rendering, committing, or running an effect; if teardown originates there, schedule it outside React work, for example with queueMicrotask(() => app.destroy()).

Components

| | | | ------------------- | ------------------------------------------------------------------------------------------------------- | | Primitives | Box Text RichText | | Layout | Panel (titled/footered border, focus color) · StatusBar | | Lists | List (selection, full-row highlight, scroll-into-view) · VirtualList · Select | | Interaction | ScrollView · Hoverable · CommandPalette | | Content | Markdown · Code · Diff · StreamingMarkdown | | Charts | BarChart Histogram Sparkline Gauge LineChart Scatter | | Hooks / helpers | useFocusList · nextFocus · listCounter · clampScroll · filterCommands · renderNodeToElement |

The components, content, and charts are included in this package's published output. You do not need to install Uniview implementation packages separately.

Advanced: custom surfaces and no-framework UI

The binding re-exports common core facilities, so tests and custom React mount flows can still use one package:

import {
  createTuiReactRoot,
  MemoryCellSurface,
  StyleTable,
} from "@uniview/tui-react";

const styles = new StyleTable();
const surface = new MemoryCellSurface({ styles });
const root = createTuiReactRoot({
  surface,
  styles,
  size: { width: 80, height: 24 },
});

For a custom terminal surface or a UI with no React/Solid runtime, install core directly:

pnpm add @uniview/tui-core
import { createTuiApp } from "@uniview/tui-core";

const app = createTuiApp({ input: process.stdin, output: process.stdout });

Working demos

Notes

Component sources are .ts, not .tsx. They use createElement directly, because this package's tsconfig has no jsx option — adding .tsx sources breaks check-types. Tests are .tsx.

List is controlled, and deliberately tracks a "last requested" index. selectedIndex only becomes the new prop once the parent re-renders, so two ArrowDowns dispatched in one tick would otherwise both read the stale value and collapse into a single step. Don't "simplify" that ref away — a test pins it.

Keys route to the focused node, bubbling to the nearest ancestor with an onKeyDown. In tests, dispatchInput(key("Tab")) first or nothing is focused. Digits arrive as text events; named keys as key events.

Development

pnpm test          # vitest
pnpm check-types   # tsc --noEmit — vitest and tsdown do NOT type-check
pnpm build         # tsdown