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

npx-skills

v0.1.0

Published

CLI to install opencode AI agent skills

Readme

node-binary-package-template

A minimal, production-ready template for building Node.js CLI tools with TypeScript. Clone this repo, rename a few fields, and you have a working npx my-command binary ready to publish to npm.

The included example command prints the caller's current working directory — the project where someone runs the command, not where your package is installed.


Table of contents

  1. Prerequisites
  2. Project structure
  3. Quick start
  4. Development workflow
  5. Testing locally
  6. Installing in another project
  7. Publishing to npm
  8. Customizing — renaming your command
  9. How process.cwd() works
  10. Scripts reference

Prerequisites

| Tool | Minimum version | |------|----------------| | Node.js | 18 | | npm | 7 |


Project structure

.
├── src/
│   └── index.ts        # Your CLI source code (edit this)
├── dist/               # Compiled output — generated by the build, do not edit
├── tsup.config.ts      # Bundler configuration
├── tsconfig.json       # TypeScript configuration
├── package.json
├── .gitignore
├── .npmignore
└── README.md

dist/ is gitignored and regenerated on every build. It is the only folder published to npm (controlled by the files field in package.json).


Quick start

1. Clone the template

git clone https://github.com/your-username/node-binary-package-template.git my-new-cli
cd my-new-cli

2. Remove the template's git history and start fresh

rm -rf .git
git init
git add .
git commit -m "Initial commit from template"

3. Install dependencies

npm install

4. Build and run

npm run build        # compiles src/ → dist/
node dist/index.js   # run it directly

You should see output similar to:

Current project directory:
/Users/you/projects/my-new-cli

Contents:
  [dir]  node_modules
  [file] package.json
  [file] tsconfig.json
  ...

Development workflow

One-time build

Compiles TypeScript and bundles everything into dist/index.js.

npm run build

Live build (watch mode)

Re-compiles automatically every time you save a file in src/.

npm run dev

Leave this running in a terminal while you edit src/index.ts. Each save triggers a rebuild, so you can test changes immediately with node dist/index.js.

Type checking

Runs the TypeScript compiler without emitting files, just to catch type errors.

npm run typecheck

Testing locally

Option A — npm link (recommended for repeated testing)

npm link installs your package globally on your machine, making the command available everywhere as if it were published to npm.

Step 1 — register the package globally from your template directory:

cd /path/to/my-new-cli
npm run build          # dist/ must exist before linking
npm link

Step 2 — use the command from any directory:

cd /some/other/project
my-command

To unlink when you are done:

npm unlink -g my-command

If you rename the command in package.json you must re-run npm link.

Option B — npx with a local path (no global install)

npm run build
npx /path/to/my-new-cli

This is useful for quick one-off tests without touching your global npm environment.

Option C — run the compiled file directly

node dist/index.js

Installing in another project

From npm (after publishing)

# As a dev dependency (tool used during development)
npm install --save-dev my-command

# As a regular dependency
npm install my-command

Then run it via an npm script in that project's package.json:

{
  "scripts": {
    "my-script": "my-command"
  }
}

Or invoke it directly through npm:

npx my-command

From a local path (before publishing)

Useful when you want to test your CLI inside another project without publishing to npm first.

cd /path/to/other-project
npm install /path/to/my-new-cli

Then run:

npx my-command
# or add it to scripts in package.json and use: npm run my-script

Publishing to npm

First-time setup

  1. Create an account at npmjs.com if you don't have one.
  2. Log in from your terminal:
    npm login

Publish

npm run build      # always build before publishing
npm publish

For scoped packages (e.g. @your-username/my-command):

npm publish --access public

Updating the version

npm version patch   # 0.1.0 → 0.1.1  (bug fix)
npm version minor   # 0.1.0 → 0.2.0  (new feature)
npm version major   # 0.1.0 → 1.0.0  (breaking change)
npm publish

npm version automatically commits and tags the version bump in git.


Customizing — renaming your command

Everything that needs to change when you rename my-command to something else:

1. package.json — three fields

{
  "name": "your-package-name",
  "description": "What your tool does",
  "bin": {
    "your-command-name": "./dist/index.js"
  }
}
  • name — the npm package name (what people npm install).
  • bin key — the executable name (what people type in the terminal).

They can be different. For example: package name is @acme/tools, bin key is acme.

2. Re-link if you used npm link

npm unlink -g my-command
npm link

3. That's it

src/index.ts and all build configuration stay the same.


How process.cwd() works

process.cwd() returns the current working directory of the shell that invoked the command, not the directory where your package lives.

/home/user/projects/my-app/    ← process.cwd() when run from here
└── node_modules/
    └── my-command/            ← __dirname / import.meta.url point here
        └── dist/
            └── index.js

This means your CLI always knows where the user is, regardless of where npm installed it. Use process.cwd() to:

  • Read config files from the caller's project (e.g. path.join(process.cwd(), 'package.json'))
  • Generate files inside the caller's project
  • Walk the caller's directory tree

Do not use __dirname for this purpose — __dirname points at your package's installation directory.


Scripts reference

| Script | Command | Description | |--------|---------|-------------| | build | tsup | Compile src/ to dist/ once | | dev | tsup --watch | Rebuild on every file save | | start | node dist/index.js | Run the compiled binary | | typecheck | tsc --noEmit | Type-check without emitting files | | prepare | npm run build | Runs automatically before npm publish and after npm install from a git URL |