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

silvery

v0.3.0

Published

React terminal UI renderer for complex interactive apps — layout-aware rendering, flexbox, scrolling, and incremental updates

Downloads

180

Readme

Silvery

Polished Terminal UIs in React.

Responsive layouts, scrollable containers, 100x+ faster incremental updates, and full support for modern terminal capabilities. 30+ components from TextInput to VirtualList. Pure TypeScript, no WASM.

npm install silvery react

Status: Alpha — under active development. APIs may change. Early adopters and feedback welcome.

import { useState } from "react"
import { render, Box, Text, useInput, useContentRect, createTerm } from "silvery"

function App() {
  const { width } = useContentRect()
  const [count, setCount] = useState(0)

  useInput((input) => {
    if (input === "j") setCount((c) => c + 1)
    if (input === "k") setCount((c) => c - 1)
    if (input === "q") return "exit"
  })

  return (
    <Box flexDirection="column" padding={1}>
      <Text bold>Counter ({width} cols wide)</Text>
      <Text>Count: {count}</Text>
      <Text dim>j/k = change, q = quit</Text>
    </Box>
  )
}

using term = createTerm()
await render(<App />, term).run()

Renderer

Responsive layout

useContentRect() returns actual dimensions synchronously -- no post-layout effect, no {width: 0, height: 0} on first render. Components adapt to their available space immediately.

function Responsive() {
  const { width } = useContentRect()
  return width > 80 ? <FullDashboard /> : <CompactView />
}

Scrollable containers

overflow="scroll" with scrollTo -- the framework handles measurement, clipping, and scroll position. No manual virtualization needed.

<Box height={20} overflow="scroll" scrollTo={selectedIndex}>
  {items.map((item) => (
    <Card key={item.id} item={item} />
  ))}
</Box>

Per-node dirty tracking

Seven independent dirty flags per node. When a user presses a key, only the affected nodes re-render -- bypassing React reconciliation entirely for unchanged subtrees. Typical interactive updates complete in ~170 microseconds for 1000 nodes, compared to full-tree re-renders.

Multi-target rendering

Terminal today, Canvas 2D and DOM experimental. Same React components, different rendering backends.

Framework Layers (Optional)

Input layer stack

DOM-style event bubbling with modal isolation. Opening a dialog automatically captures input -- no manual guard checks in every handler.

<InputLayerProvider>
  <Board />
  {isOpen && <Dialog />} {/* Dialog captures input; Board doesn't see it */}
</InputLayerProvider>

Spatial focus navigation

Tree-based focus with scopes, arrow-key directional movement, click-to-focus, and useFocusWithin. Go beyond tab-order.

Command and keybinding system

Named commands with IDs, help text, configurable keybindings, and runtime introspection. Build discoverable, AI-automatable interfaces.

const MyComponent = withCommands(BaseComponent, () => [
  { id: "save", label: "Save", keys: ["ctrl+s"], action: () => save() },
  { id: "quit", label: "Quit", keys: ["q", "ctrl+c"], action: () => exit() },
])

Mouse support

SGR mouse protocol with DOM-style event props -- onClick, onMouseDown, onWheel, hit testing, drag support.

Multi-line text editing

Built-in TextArea with word wrap, scrolling, cursor movement, selection, and undo/redo via EditContext.

30+ built-in components

TextArea, TextInput, VirtualList, SelectList, Table, CommandPalette, ModalDialog, Tabs, TreeView, SplitView, Toast, Image, and more -- all with built-in scrolling, focus, and input handling.

Theme system

@silvery/theme with 38 built-in palettes and semantic color tokens ($primary, $error, $border, etc.) that adapt automatically.

TEA state machines

Optional Elm Architecture alongside React hooks. Pure (action, state) -> [state, effects] functions for testable, replayable, undoable UI logic.

Packages

| Package | Description | | ------------------------------------ | ----------------------------------------- | | silvery | Umbrella -- re-exports @silvery/react | | @silvery/react | React reconciler, hooks, renderer | | @silvery/term | Terminal rendering pipeline, ANSI styling | | @silvery/ui | Component library (30+ components) | | @silvery/theme | Theming with 38 palettes | | @silvery/tea | TEA state machine store | | @silvery/compat | Ink/Chalk compatibility layers | | @silvery/test | Testing utilities and locators |

Compatibility

silvery/ink and silvery/chalk provide compatibility layers for existing React terminal apps. The core API (Box, Text, useInput, render) is intentionally familiar -- most existing code works with minimal changes. See the migration guide for details.

When to Use Silvery

Silvery is designed for complex interactive TUIs — dashboards, editors, kanban boards, chat interfaces. If you need scrollable containers, mouse support, spatial focus, or components that adapt to their size, Silvery provides these out of the box.

For simple one-shot CLI prompts or spinners, mature alternatives with larger plugin ecosystems may be a better fit today.

Ecosystem

| Project | What | | ------------------------------------------ | -------------------------------------------------------------- | | Termless | Headless terminal testing -- like Playwright for terminal apps | | Flexily | Pure JS flexbox layout engine (Yoga-compatible, zero WASM) | | Loggily | Debug + structured logging + tracing |

See the roadmap for what's next.

Performance

Apple M1 Max, Bun 1.3.9. Reproduce: bun run bench:compare

| Scenario | Silvery | Ink 5 | | --------------------------------------- | ------- | ------- | | Cold render (1 component) | 165 us | 271 us | | Cold render (1000 components) | 463 ms | 541 ms | | Typical interactive update (1000 nodes) | 169 us | 20.7 ms | | Layout (50-node kanban) | 57 us | 88 us |

Why the difference? Interactive updates (cursor move, scroll, toggle) typically change one or two nodes. Silvery's per-node dirty tracking updates only those nodes — 169 us for a 1000-node tree. Traditional full-tree renderers re-render the entire React tree and run complete layout on every state change — 20.7 ms. For the updates that dominate interactive use, Silvery is ~100x faster.

Full re-renders where the entire tree changes are comparable or faster in full-tree renderers (simpler string concatenation vs Silvery's 5-phase pipeline). That trade-off is inherent to supporting responsive layout, and full re-renders are rare in interactive apps.

Documentation

Full docs at silvery.dev -- getting started guide, API reference, component catalog, and migration guide.

Development

bun install
bun test
bun run lint

License

MIT