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

index-n2

v0.1.0

Published

Local viewer for fieldtheory-cli bookmarks. Reads from ~/.ft-bookmarks/.

Readme

index-n2

A local viewer for fieldtheory-cli. Runs a Node server on localhost:5787 and opens a browser tab. Reads from ~/.ft-bookmarks/; writes derived caches to ~/.index-n2/.

Third-party tool, not affiliated with fieldtheory-cli.

Made for Macintosh. The GUI runs anywhere; the CLI's default sync targets macOS. For cross-platform options, see the CLI's ft sync --api mode and its caveats.


Install

npm install -g index-n2

Requires Node.js and a working fieldtheory-cli install on PATH. No bookmark data needed up front — first sync runs from the sidebar.

Run

index-n2

The server binds 127.0.0.1:5787 and opens http://localhost:5787/. If 5787 is taken it walks up to 5797. Stop with Ctrl-C.


Overview

Reads ~/.ft-bookmarks/bookmarks.jsonl and bookmarks.db directly. Renders the result as a masonry grid, gallery, lightbox, and duplicates view. Filters across author, type, language, category, color, and full-text search. Wraps ft sync, ft fetch-media, and ft sync --rebuild as sidebar actions with live progress over Server-Sent Events.

~/.ft-bookmarks/ is treated as read-only. The GUI never writes, deletes, or modifies anything inside it. All derived data — thumbnails, color palette cache, dedup index, archive list, settings — lives in ~/.index-n2/ and is rebuildable from scratch.

CLI features re-implemented client-side

| Feature | CLI equivalent | | ------------------- | -------------------- | | Full-text search | ft search | | Filter by author | ft list --author | | Filter by category | ft list --category | | Sort by date | ft list --sort |

CLI commands wrapped

| Action | Shells out to | | ----------------- | ------------------------------- | | Sync All | ft sync then ft fetch-media | | Sync Bookmarks | ft sync | | Fetch Media | ft fetch-media --limit N | | Rebuild Bookmarks | ft sync --rebuild --yes |

GUI-original

  • Color filter. A dominant palette is extracted per image (median-cut RGB quantization, palette stored in Lab D65 for matching) and cached on disk. A picked hex matches palette entries via population-weighted ΔE with a lightness-aware threshold; a separate mono mode matches images whose chroma falls below ~12.
  • Duplicate detection. 64-bit pHash (32×32 → 2D DCT → 8×8 low-frequency block, median threshold) with a 9-bit Hamming radius for images; exact-match grouping over normalized text. Profile pictures and solid-color images are excluded.
  • Type filter — text, image, video, gif, link, quoted, thread.
  • Sort by engagement — likes, reposts, bookmarks, or random.
  • Gallery view. Image-only, flattened across bookmarks.
  • Archive. Hide bookmarks from the main grid without touching source data.

Configuration

In-app settings

Persisted in ~/.index-n2/settings.json. Edit through the gear icon in the sidebar.

| Key | Default | Effect | | ------------------- | ------- | --------------------------------------------------- | | theme | system | system / light / dark | | autoplayVideos | true | Auto-start videos in the lightbox | | autoOpenBrowser | true | Open a browser tab on startup (restart to apply) | | skipMedia | false | Sync runs ft sync --no-media (bookmarks only) | | mediaFetchLimit | 0 | Cap for ft fetch-media --limit. 0 disables it. | | skipProfileImages | false | Adds --skip-profile-images to ft fetch-media | | hideUnfetched | false | Hide bookmarks with media pending download |

Two additional keys are flipped by "Don't show this again" checkboxes on confirmation dialogs, not the gear icon: cancelMediaWarningSuppressed (cancel fetch-media) and noLimitWarningSuppressed (no-batch-limit warning shown before unbounded Sync / Fetch Media). Reset to Defaults clears all nine.

Unknown keys are stripped on the next save; defaults backfill missing keys. Schema migrations are self-healing.

Environment

| Variable | Default | Effect | | -------------- | ----------------- | -------------------------------------------------------- | | FT_DATA_DIR | ~/.ft-bookmarks | Override the ft data directory | | PORT | 5787 | Pin the port. Disables the auto-fallback on collision. | | BROWSER=none | unset | Skip browser auto-open even if the setting is enabled | | CI | unset | Skip browser auto-open |

Flags

index-n2 --no-open      Skip browser auto-open for this run

Layout

~/.ft-bookmarks/                  fieldtheory-cli, read-only to this app
  bookmarks.jsonl                 raw bookmark records
  bookmarks.db                    SQLite, opened read-only via sql.js-fts5
  media-manifest.json             URL → local-path map
  media/                          downloaded media

~/.index-n2/              derived; safe to delete and rebuild
  thumbnails/                     1200px JPEGs (only for media > 1200px)
  colors.json                     per-image Lab palettes
  dedup.json                      pHash + text-match cache
  archived.json                   archived bookmark IDs
  settings.json                   user settings

index-n2 process          localhost:5787
  server.js                       API + static + media + image pipeline
  dist/                           Vite build (React 19, TS, Tailwind 4, shadcn/ui)

Per-file caches (palette, pHash, thumbnails) are keyed by media filename and grow incrementally — only files in ~/.ft-bookmarks/media/ that aren't already in the cache trigger work. Bookmark records reload when bookmarks.jsonl or the SQLite mtime changes.


Security

The server is a localhost-only Node process. Defenses:

  • Bind to 127.0.0.1.
  • Origin check on writes. Every mutating endpoint requires an Origin header resolving to localhost or 127.0.0.1. Cross-origin POSTs return 403.
  • Path traversal + symlink escape guard. Every static-file request — /media/, /thumbs/, and the SPA bundle in dist/ — is resolved lexically, then realpath-validated to lie under its base directory.
  • Media extension whitelist. Image and video formats only — no SVG, no HTML.
  • Strict CSP. No remote scripts; the only inline script is hash-allowlisted. Styles, images, fonts, and media follow standard SPA carve-outs.
  • Subprocess discipline. Spawned ft processes time out at 5 min idle (not wall-clock). Cancel sends SIGINT on Unix.

No remote endpoints are contacted. All media is read from ~/.ft-bookmarks/media/, which ft itself populates.


Limitations

  • Categories are read-only. No in-app classification editor.
  • Cancelling ft fetch-media mid-run leaves orphaned files on disk: ft writes its manifest at end-of-run, so a cancelled batch's downloads are invisible to ft and re-fetched next time. Bandwidth waste, no corruption. Tracked upstream.
  • A small set of permanently unfetchable URLs (deleted tweets, protected accounts) keep the "N unfetched" badge non-zero.

Development

git clone https://github.com/refractionweb/index-n2.git
cd index-n2
npm install

Two-process dev loop:

node server.js      # API on :5787
npm run dev         # Vite on :5173, proxies /api /media /thumbs to :5787

Production build:

npm run build       # tsc -b && vite build
npm start           # serves dist/ from server.js

Other tasks:

npm run typecheck
npm run lint
npm run format

The codebase is React 19 + TypeScript + Vite + Tailwind 4 + shadcn/ui. State is React Context + useReducer, split per concern under src/contexts/. No Redux, no Zustand. Path imports use @/ for src/. Styling sticks to shadcn semantic tokens; deviations are recorded inline next to the code that needs them.


Credits

Built on open source:

License

MIT License · Copyright © 2026 Refraction