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

@gtbuchanan/cli

v0.6.0

Published

Shared build CLI

Readme

@gtbuchanan/cli

Shared build CLI for JavaScript/TypeScript projects. Provides the gtb binary: user-invoked commands (verify, sync, turbo, prepare) at the root, and leaf tool wrappers under gtb task <name> for Turborepo to call via generated package.json scripts.

Install

pnpm add -D @gtbuchanan/cli

Usage

After installing, generate your turbo.json and per-package scripts:

pnpm exec gtb sync

This reconciles turbo.json, tsconfigs, package.json scripts, and codecov.yml with the current workspace. Re-run after adding packages or changing capabilities.

Run the pipeline via the gtb turbo wrapper (generated root scripts delegate to it so Android/Termux users get a transparent escape hatch):

pnpm exec gtb turbo run check   # compile → lint + test:fast (parallel)
pnpm exec gtb turbo run build   # full pipeline
pnpm exec gtb turbo run test:fast

Monorepos also get pnpm check / pnpm build aliases for these. A single-package repo (where the root is the package) gets none: a root script named after an aggregate makes turbo re-enter itself, so the gtb turbo run form above is the entry point there.

gtb turbo is a thin pass-through to turbo on every supported platform. On Android, process.platform === 'android' causes the node_modules launcher to refuse to start; the wrapper resolves the native turbo from Termux's package registry and execs it directly. Install it once per Termux environment:

pkg install turbo

That puts a Bionic-built turbo at $PREFIX/bin/turbo (typically /data/data/com.termux/files/usr/bin/turbo), which gtb turbo resolves and execs.

The Termux-pkg turbo is Bionic-built, so its child-process spawns honor Termux's LD_PRELOAD shebang rewriter and resolve #!/usr/bin/env <name> correctly. @gtbuchanan/pnpm-termux-shim is retained defensively in case turbo reintroduces a glibc npm distribution, or another glibc binary in the graph needs to spawn pnpm. Add it to your workspace root package.json optionalDependencies (not inside any individual package — under pnpm strict layout, only the root's node_modules/.bin/ is on turbo's PATH at spawn time). The shim's os: ["android"] filter keeps it off non-Android hosts.

The prepare script must be declared so pnpm runs it on install to sync skills from installed packages:

{
  "scripts": {
    "prepare": "gtb prepare"
  }
}

Use verify in CI to detect drift between the generated config and the current workspace state:

pnpm exec gtb verify

Commands

Root commands are user-invoked. task <name> dispatches to a single leaf tool and forwards extra arguments; Turborepo invokes leaves through generated package.json scripts ("typecheck:ts": "gtb task typecheck:ts").

Root commands

| Command | Purpose | | --------- | ------------------------------------------------------- | | verify | Validate generated config against workspace state | | sync | Reconcile turbo.json, tsconfigs, scripts, codecov.yml | | turbo | Run turbo (with an Android escape hatch) | | prepare | Sync skills from installed packages |

Task leaves (gtb task <name>)

| Name | Tool | | ------------------------- | -------------------------------------------------------------------------------------------- | | compile:skills | Copy skills/ into dist/source/skills/ | | compile:ts | tsc -p tsconfig.build.json | | coverage:codecov:upload | Upload lcov to Codecov (requires codecov CLI) | | coverage:vitest:merge | vitest --merge-reports (fast + slow) | | deploy:skills | Symlink skills into project-local agent dirs via skills add | | typecheck:ts | tsc --noEmit | | lint:eslint | eslint --max-warnings=0 | | pack:npm | Generate manifest + pnpm pack (per-pkg) | | test:vitest | vitest run | | test:vitest:fast | vitest run --tags-filter='!slow' | | test:vitest:slow | vitest run --tags-filter=slow | | test:vitest:e2e | vitest run --config vitest.config.e2e.ts |

Leaves forward extra arguments to the underlying tool:

gtb task test:vitest --reporter=verbose
gtb task test:vitest --tags-filter='!slow && !db'
gtb task lint:eslint --fix
gtb sync --force              # overwrite existing scripts

Test tags

test:vitest:fast and test:vitest:slow use Vitest's --tags-filter to split tests by the slow tag. See @gtbuchanan/vitest-config for how to tag tests and configure custom tags.

gtb commands are non-interactive (run-once). For watch mode and the Vitest UI, run vitest directly:

pnpm exec vitest --ui --coverage.reporter=html
pnpm exec vitest --watch --tags-filter='!slow'

Design

Why a custom CLI alongside Turborepo?

Turborepo orchestrates scripts that each repo defines — consumers still specify what lint or compile means in every repo. gtb centralizes those definitions so consumers inherit them by installing one package. This is closer to what react-scripts does for Create React App.

Turborepo provides the orchestration layer (caching, dependency graphs, incremental builds, parallel execution). gtb provides the tool definitions layer (what each command runs, with what flags). The two are complementary: sync generates the turbo.json pipeline and package.json scripts that delegate to gtb task <name> leaves.

Code generation

Projects that use code generation (Paraglide, Prisma, protobuf, etc.) should define generate:<tool> scripts in their package.json:

{
  "scripts": {
    "generate:prisma": "prisma generate",
    "generate:paraglide": "paraglide-js compile"
  }
}

sync discovers these scripts and wires them into the pipeline automatically. The generate aggregate runs before typecheck:ts, compile:ts, and all lint tasks, so generated code is always available when those steps execute.

Prefer standalone generation over build plugins. Embedding generation in a build plugin (e.g., Vite Paraglide plugin) breaks Turborepo's cache granularity — the generation step can't be cached independently, and typecheck can't run until the full build completes. Standalone generate:<tool> scripts have explicit inputs and outputs that Turborepo caches individually.

Define inputs and outputs in a per-package turbo.json:

{
  "extends": ["//"],
  "tasks": {
    "generate:prisma": {
      "inputs": ["prisma/schema.prisma"],
      "outputs": ["src/generated/**"]
    }
  }
}

Agent Skills

gtb ships opt-in support for Agent Skills.

Consuming skills from installed packages

Add skills-npm as a devDep:

pnpm add -D skills-npm

gtb prepare invokes skills-npm --recursive --yes on every pnpm install, symlinking skills from every installed package into the directories of the coding agents detected on your machine. Silently skipped if skills-npm isn't installed. See skills-npm for a skills-npm.config.ts if you need to pin specific agents or filter which packages get scanned.

Authoring skills in your packages

Place SKILL.md files under packages/<pkg>/skills/<name>/ with the required frontmatter (name, description). Pick a globally unique name — prefix with your scope (e.g. acme-foo) to avoid collision with other published packages.

Run gtb sync. Packages with a skills/ directory gain:

  • compile:skills — copies skills/ into dist/source/skills/ before pack:npm, shipping them to consumers via the published tarball
  • deploy:skills — symlinks skills into project-local agent directories (./.claude/skills/, ./.codex/skills/, etc.) for dogfooding; requires skills (Vercel Labs) as a devDep:
pnpm add -D skills
pnpm deploy:skills

Workspace detection

pack supports both monorepo and single-package layouts:

  • Monorepo — Detected via pnpm-workspace.yaml with a non-empty packages field. Iterates over all resolved package directories.
  • Single-package — Fallback when no workspace file or packages are found. Operates on the current working directory.