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

hn-bits

v0.8.0

Published

Terminal-first Hacker News client

Readme

hn-bits

A fullscreen terminal client for Hacker News, built with TypeScript + Ink. Optional local AI summaries via Ollama, topic subscriptions with Telegram alerts, no cloud required beyond what you opt into.

npm version CI Release npm downloads License

Streaming article summary, then a multi-turn Ask AI conversation grounded in the same story

Subs tab: manage topic subscriptions, browse per-topic matches

Saved tab: bookmark a story with B, browse it from hn bookmarks

Features

  • Fullscreen TUI: top/new/best/ask/show/saved/subs tabs, vim-style navigation
  • Threaded comments view with fold/collapse
  • Search across stories
  • 7 built-in themes (hn, mocha, dracula, tokyo, nord, gruvbox, concord)
  • Local AI article/thread summaries via Ollama, no cloud calls
  • Ask AI: multi-turn Q&A grounded in the current story
  • Subscriptions + hn watch --once radar with Telegram notifications
  • Bookmarks: B to save a story, hn bookmarks to browse them
  • SQLite storage (subscriptions, dedup, bookmarks); config file for AI/Telegram settings

Install

npm install -g hn-bits

Or run without installing:

npx hn-bits

From source

npm install
npm run build
npm link   # exposes the `hn` binary

Usage

hn                    # fullscreen shell: top/new/best/ask/show/saved/subs tabs
hn search <query...>  # search results
hn bookmarks          # opens straight into the saved tab
hn subs               # opens straight into the subs tab
hn --theme dracula    # themes: hn (default), mocha, dracula, tokyo, nord, gruvbox, concord

Press ? from any view for the full keybinding help overlay.

Local AI (summaries + Ask AI)

Article/thread summaries (s) and interactive Q&A (a) run against a local Ollama instance, no cloud calls, no API keys. Optional: the app works fully without it, s/a just show a setup hint until configured.

Prerequisites

brew install ollama   # or see ollama.com/download
ollama serve           # if not already running as a service
ollama pull llama3.2    # or any other chat-capable model

Setup (one-time):

hn config set ollama.host http://localhost:11434
hn config set ollama.model llama3.2

Missing fields fall back to the defaults above; invalid JSON degrades to "AI disabled" with a warning rather than crashing the reader.

Subscriptions + notifications

hn sub tracks topic queries; hn watch --once checks each one, dedups against past matches, and sends new ones to Telegram and/or macOS desktop notifications. No daemon: schedule hn watch --once with cron or launchd.

hn sub add apple "Apple" --min-points 50   # topic name, Algolia query, min score
hn sub list
hn sub rm apple

Telegram setup (one-time):

  1. Message @BotFather on Telegram, run /newbot, copy the token it gives you.
  2. Message your new bot once (anything, e.g. "hi").
  3. Fetch https://api.telegram.org/bot<TOKEN>/getUpdates and read result[0].message.chat.id.
hn config set telegram.botToken 123456:ABC-...
hn config set telegram.chatId 987654321
hn config set telegram.enabled true

All three keys are required, telegram.enabled alone is not enough. With nothing enabled, hn watch --once exits with code 2.

macOS desktop notifications (optional, works alone or alongside Telegram) use the alerter binary (brew install vjeantet/tap/alerter):

hn config set desktopNotifications.enabled true
hn config set desktopNotifications.timeoutSeconds 10   # optional, default 10

Clicking a notification opens the story URL (HN discussion for text posts): clicks act only while the notification is on screen (timeoutSeconds); stale entries in Notification Center just dismiss. Desktop delivery is best-effort: if alerter is missing, the watcher warns and skips it (exit 0, nothing marked seen when it's the only channel).

One-time macOS setup: alerter sends as Terminal.app, and macOS silently drops notifications from senders without permission. Check System Settings > Notifications > Terminal is allowed (banner style): there is no prompt and no error when it isn't.

hn watch --once   # one pass: query subscriptions, notify new matches, exit

The first hn sub add offers to install a cron job for you (every 30 minutes). Manage it anytime via the CLI, or c on the Subs tab (which also shows a live installed/not-installed status line):

hn schedule status   # installed / not installed
hn schedule install  # install now (no-op if already installed)
hn schedule remove   # uninstall

Or set it up by hand:

*/30 * * * * cd /path/to/hn-bits && hn watch --once

Configuration

hn config reads/writes ~/.config/hn-bits/config.json (override the path with $HN_BITS_CONFIG), no need to hand-edit JSON:

hn config list                        # every known key + current value
hn config get ollama.model            # single value, raw
hn config set ollama.model llama3.2   # validates + writes
hn config unset ollama.model          # removes a key

Sensitive values (e.g. telegram.botToken) print masked in list but raw from get, so scripts can still consume them. File format is plain JSON; hand-editing still works if you prefer it.

Themes

hn, mocha, dracula, tokyo, nord, gruvbox, concord (default: hn, HN-orange). Pick with --theme <name>, the HN_THEME env var, hn config set ui.theme <name>, or press T in the TUI to switch live and persist the choice. Precedence: flag > env > config > default. hn theme shows the active theme and where it came from.

Keybindings

Global

| Key | Action | |-----|--------| | q | quit (suppressed while typing in search) | | ? | help overlay (suppressed while typing in search) |

Story list

| Key | Action | |-----|--------| | j/k or ↓/↑ | move selection | | / | previous/next feed tab | | t/n/b | top / new / best directly | | g g / G | top / bottom | | enter | open comments | | o | open story URL in browser | | r | refresh feed | | / | search | | s | AI summary (article, or thread if no article) | | a | Ask AI (chat grounded in the story) | | B | bookmark |

Comments

| Key | Action | |-----|--------| | j/k or ↓/↑ | move selection | | space/enter | toggle fold on a comment | | C/E | collapse / expand all | | g g / G | top / bottom | | o | open story URL in browser | | r | reload | | s | AI thread summary | | a | Ask AI (chat grounded in the story) | | B | bookmark | | esc/b | back |

Search results

Same as story list, minus the tab/feed keys, plus / to start a new search and S to subscribe (prefills a topic from the query). esc returns to the list if you got here via / in-TUI, or quits if you entered via hn search.

Saved (hn bookmarks, or the Saved tab)

Same as story list, minus search; B removes a bookmark instead of adding one.

Subs (hn subs, or the Subs tab)

| Key | Action | |-----|--------| | j/k or ↓/↑ | move selection | | / | previous/next tab | | enter | browse matches for the selected topic | | a | add subscription | | e | edit subscription | | d | delete subscription | | c | toggle watch cron schedule (install/remove) |

Shows a schedule: installed (every 30 min) / schedule: not installed status line, so you don't need to drop to hn schedule status to check.

Sub matches (opened from Subs via enter)

Same as story list, minus search/tab-switch; r refetches, esc returns to Subs.

Development

npm run dev    # run from source (tsx)
npm test       # vitest
npm run build  # tsc

Tech stack

  • TypeScript (strict, ESM) + Ink (React for terminals)
  • Commander CLI, native fetch
  • HN Firebase + Algolia APIs, no backend
  • better-sqlite3 for subscriptions/dedup/bookmarks
  • Vitest

Specs

Implementation specs live in specs/; phase-by-phase status is tracked in PROGRESS.md. V1, V1.5, V1.6, V2 (local AI), and V3 (subscriptions/watcher/notifications/bookmarks) are feature-complete.