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

issue-commander

v0.1.3

Published

A Total Commander–style two-pane manager for GitHub issues — triage across repositories, org-wide milestones, and Projects with function keys.

Readme

Issue Commander

A two-pane manager for GitHub issues and pull requests, in the tradition of the orthodox file managers — Norton Commander, Total Commander, and Midnight Commander (mc). Point each pane at a repository, an org-wide milestone, or a GitHub Project (V2), then triage with function keys (F3–F8) — the way you move files in a two-pane file manager. Everything stays scoped to one GitHub organization.

npx issue-commander --org your-org
# → http://localhost:7367

Why

GitHub shows one issue, in one repo, in one tab. Triaging across repos, a milestone, or a project board means constant clicking and context-switching. Issue Commander puts two panes side by side and drives every action from the keyboard, so you reorganize issues as fast as you move files in a two-pane file manager.

Requirements

  • Node 20+
  • GitHub CLI, authenticated. The token comes from gh auth token (falling back to GITHUB_TOKEN / GH_TOKEN); run gh auth login once. It needs the repo, read:org, and project scopes.
  • A target organization — pass --org <org>, or set IC_GITHUB_ORG (or the legacy GITHUB_ORG). There is no in-app org switch. See Configuration.
gh auth login
npx issue-commander --org acme                  # serve on port 7367
npx issue-commander --org acme --port 3002      # custom port
IC_GITHUB_ORG=acme npx issue-commander          # via the environment instead of a flag

The two panes

Each pane points at a source and lists its rows in a dense, resizable table. You act from the active pane onto the other one: put the cursor on a row, press a function key, and it operates on whatever the opposite pane shows. Press F6 on the left pane to move that issue into the right pane's project:

| 🏁  milestone: 42 · F1 | 📋  Project: Q3 Roadmap · F2 | | ---------------------------------- | ------------------------------------------ | | #812 Fix flaky upload test | #640 Onboarding revamp ● Todo | | #815 Login throttling ◀ cursor | #641 Billing page ● In Progress | | #820 Stripe webhook retry | #655 Dark mode ● Done | | #828 Rate-limit headers | #660 CSV export ● Todo |

Sources a pane can show

| Source | What it lists | Last column | | -------------- | -------------------------------------------------------------------- | ----------- | | Repository | Issues (or pull requests) in one repo, via REST | Milestone | | Milestone | Issues with that milestone title across every repo, via Search | Repo | | Project | Items on a Projects V2 board, with their Status, via GraphQL | Repo | | Recent | Issues you're involved in, most-recently-updated first, via Search | Repo |

Issues or pull requests

A repository pane carries an Issues / Pull Requests tab. Switch to pull requests and each row shows its author, target branch, and merge status — open, merged, or closed, marked by the row icon. Filter by state (Open / Merged / Closed / All), by target branch, or by author. Pull-request rows are read-only here: open one on GitHub with Enter, or preview it with F3.

Filter by date. Every pane has a date filter that follows the state you're viewing: it ranges over the opened date for open items, the closed date for closed ones, and the merged date for merged pull requests. Pick a preset (last 7, 30, or 90 days) or an exact From / To — so "everything merged in the last three days" is a couple of clicks.

Columns in the issue view

| Column | Notes | | -------------------- | ----------------------------------------------------------------------------- | | # | Issue number and open/closed icon; click any header to sort | | Title | Double-click to open the issue on GitHub | | Assignee | Overlapping avatar stack, with a +N overflow | | Labels | GitHub colors, with a +N overflow | | Status | The issue's Project Status (Todo / In Progress / Done …); see note | | Repo / Milestone | Contextual last column, set by the source |

Status on every pane. Project panes read Status from the board. Repository, milestone, and recent panes get it from a batched GraphQL lookup, so each issue shows its Project Status even when the pane is not a project. The default project you pick in Settings decides which board it reads.

What you can do

Move issues between milestones. Point the left pane at milestone: 42 and the right at milestone: 43, highlight an issue, and press F6. It moves to milestone 43 and leaves the left pane. Milestones match org-wide by title, so this works across every repo.

Copy or move between projects. Point one pane at a Projects V2 board. F5 copies the highlighted issue onto that board (an issue can belong to many projects); F6 moves it between boards, adding it to the target before removing it from the source, so membership is never lost. A cross-repo move runs a real transferIssue — new number, old URL redirects — behind a confirm dialog.

Act on many at once. Ins marks a row (yellow) and advances the cursor, so Ins Ins Ins selects a run. Then F5 / F6 / F8 (copy / move / close) or F7 (edit state, assignee, labels, milestone, status, type) act on the whole selection — concurrency-limited and optimistic, with a per-row spinner and per-row rollback on failure.

Create and preview fast. Alt+Enter opens a new-issue form in the sibling pane, pre-filled from the active pane's source and your saved defaults. F3 previews the highlighted row in the opposite pane (see below). Ctrl+U opens an inline assignee picker on the row itself.

Load lazily. Lists page in on demand and background-preload the next page every few seconds until fully loaded, keeping the previous rows on screen so a pane never flashes empty. The preview prefetches the cursor's ticket so it opens instantly, and option lists (assignees, labels, projects) persist in localStorage.

Preview (F3)

F3 previews the highlighted row in the opposite pane and follows the cursor. For an issue you get the rendered Markdown description (images included), the comments, and its parent, sub-issues, and linked pull requests. For a pull request you also get its stats — commits, changed files, additions and deletions, and the branch flow — with no code diff.

Any issue or pull request linked by URL in the body or comments appears under Mentioned Issues. Every related row — parent, sub-issue, linked, or mentioned — expands inline from its chevron to reveal that ticket's full description, without leaving the pane or opening a dialog.

Keyboard

| Key | Action | | ------------------- | --------------------------------------------------------------------- | | Tab | Switch the active pane | | ↑ ↓ · PgUp/PgDn | Move the cursor (±1 / ±10) | | Enter | Open the row on GitHub | | Ins | Select the row and advance | | F1 / F2 | Choose the source for the left / right pane | | F3 | Preview in the other pane | | F4 | Edit the description inline, in the other pane | | F5 | Copy to the other pane's project | | F6 | Move to the other pane's source | | F7 / Space | Edit fields (state, assignee, labels, milestone, status, type) | | F8 | Close the issue(s) | | Ctrl+U | Quick-assign on the highlighted row | | Alt+Enter | New issue, in the sibling pane | | Esc | Close the preview or dialog |

Every write is optimistic: the UI updates at once and rolls back with a toast if the call fails.

Settings

The button stores your default repository, milestone, and project in localStorage. These pre-fill new issues and choose which board's Status you see and edit across non-project panes. Seed them for everyone with --repo / --milestone / --project (see Configuration); the dialog then overrides that seed per browser.

Configuration

Issue Commander is configured from the command line or the environment. Flags win over environment variables, and the IC_-prefixed variables win over the legacy names.

Command-line flags

| Flag | Sets | | --------------------- | ------------------------------------------------------------------------ | | --org <org> | GitHub organization to manage (required) | | --repo <name> | Default repository — pre-fills new issues and picks the Status board | | --milestone <title> | Default org-wide milestone | | --project <number> | Default Projects V2 number | | --port <port> | Port to serve on (default 7367) | | -h, --help | Show usage and exit |

Environment variables

| Variable | Same as | Notes | | --------------------------- | ------------- | -------------------------------------------- | | IC_GITHUB_ORG | --org | Preferred; prefixed to avoid clashes | | GITHUB_ORG | --org | Legacy name, still supported | | IC_DEFAULT_REPO | --repo | | | IC_DEFAULT_MILESTONE | --milestone | | | IC_DEFAULT_PROJECT | --project | A project number | | PORT | --port | | | GITHUB_TOKEN / GH_TOKEN | — | Token fallback when gh is not authenticated |

The three defaults seed the app on first run and the in-app Settings dialog overrides them. Flags apply to the npx launcher; when running from source (pnpm dev), set the environment variables (in your shell or .env.local) instead.

# Simplest — one flag
npx issue-commander --org acme

# With defaults, on a custom port
npx issue-commander --org acme --repo web --milestone "Q3 Roadmap" --project 12 --port 3002

# Everything through the environment (e.g. a container or CI)
export IC_GITHUB_ORG=acme
export IC_DEFAULT_REPO=web
export IC_DEFAULT_MILESTONE="Q3 Roadmap"
npx issue-commander

Development

git clone … && cd issue-commander
pnpm install
echo "GITHUB_ORG=your-org" > .env.local
pnpm dev                 # webpack dev server on :3002
pnpm build && pnpm start
pnpm lint
pnpm exec tsc --noEmit

pnpm dev runs next dev --webpack on purpose. Next 16's Turbopack dev hot-reloader leaks an async-hooks map and crashes under heavy octokit churn; build and start are unaffected.

Built with Next.js 16 (App Router), React Query, Zustand, Tailwind v4, shadcn/ui, Base UI, and octokit (REST + GraphQL). See CLAUDE.md for the full architecture.

License

MIT