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

@sigx/terminal-dev

v0.13.0

Published

HMR dev runner for SignalX terminal apps - edit components, see the running TUI update live

Readme

@sigx/terminal-dev

HMR dev runner for SignalX terminal apps: run your TUI under an in-process Vite dev server, save a component file, and watch the running terminal app update in place — no restart, no lost state.

pnpm add -D @sigx/terminal-dev

Usage

sigx-terminal-dev                  # auto-detects src/main.tsx etc.
sigx-terminal-dev src/main.tsx
sigx-terminal-dev --root path/to/app
sigx-terminal-dev --config vite.config.ts   # layer a vite config on top

Point it at the module that mounts your app:

// src/main.tsx — the "mount module"
import { defineApp, terminalMount } from '@sigx/terminal';
import { App } from './App';

defineApp(<App />).mount({ fullscreen: true }, terminalMount);
  • Edit a component module (a file that calls component(...), like App.tsx): just that module re-executes; every live instance re-runs the new setup against its existing context and re-renders in place. The terminal never tears down, and state outside the edited setup (parent components, stores, module-level signals elsewhere) survives.
  • Edit the mount module (or a module nothing accepts): the app restarts in-process — clean terminal teardown, module cache dropped, entry re-imported.
  • Break the build: the error is reported (above the live region while mounted); the next successful save recovers automatically.
  • Quit with Ctrl+C: the dev process exits 0 — quitting the app is the normal end of a dev session, so wrappers like pnpm scripts don't report a failure. (Raw mode delivers Ctrl+C to the app as a key; the app's conventional exit 130 is translated by the bin. Other exit codes pass through.)

No per-file /** @jsxImportSource … */ pragma is needed: the dev runner configures the JSX transform for your .tsx (importSource @sigx/terminal), the same way core's Vite config and lynx's plugin do. Still set the matching JSX options in your app's tsconfig.json ("jsx": "react-jsx", "jsxImportSource": "@sigx/terminal") so tsc and your editor typecheck against the same runtime.

Programmatic API

import { startDev } from '@sigx/terminal-dev';

const handle = await startDev({
    entry: 'src/main.tsx',
    root: process.cwd(),
    onError: (err) => { /* entry failed to (re)start */ },
    onRestart: () => { /* entry (re)started */ },
});
// handle.server (ViteDevServer), handle.runner (ModuleRunner)
await handle.restart();   // manual in-process restart
await handle.close();

For custom Vite setups there is terminalDevPlugin() (the plugin that injects HMR identity registration + self-accept into component modules and keeps @sigx/* external for SSR) and @sigx/terminal-dev/hmr (the runtime that patches live component instances; injected automatically).

How it works

  • An in-process Vite dev server (middleware mode, silent) plus a module runner executes the app in node. @sigx/* packages stay out of the hot graph wherever possible, so the renderer's terminal state and the reactivity instance survive hot updates.
  • The plugin gives every component(...) definition a stable identity (moduleId:index). When an edited module re-executes, the HMR runtime re-runs the new setup with each live instance's existing context, swaps ctx.renderFn, and calls ctx.update() — the contract @sigx/runtime-core exposes for HMR. Factories previously defined under the same identity are repointed at the new setup too, so parents that captured a component reference before the edit (tab catalogs, navigation) mount the new code on the next visit.
  • Mount modules (those calling defineApp/renderTerminal/mountTerminal) never self-accept — re-executing one would mount a second app — so edits there surface as a full-reload, which the runner intercepts: tear down the terminal, clear the module cache, re-import the entry.

Limitations (inherent to setup-rerun HMR)

  • Signals created inside the edited component's setup are re-created (their state resets); state anywhere else survives.
  • onMounted does not re-fire for already-mounted instances on a hot update.

License

MIT