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

gitsignet

v0.2.0

Published

Git identity guard — block commits made under the wrong author, with remote-aware rules and a zero-config doctor.

Readme

gitsignet

npm version CI license: MIT

Website & docs: gitsignet.dev

Stop committing to work repos as your personal self (and vice-versa). gitsignet is a git identity guard: it blocks a commit made under the wrong author, using rules keyed off the repo's remote — so the right identity is enforced no matter where you cloned the repo.

$ git commit -m "wip"
✗ gitsignet: wrong identity for this remote — commit blocked
  remote  : github.com/acme-corp/widgets
  rule    : github.com/acme-*
  expected: Work Me <[email protected]>
  current : Personal Me <[email protected]>
  fix     : run `gitsignet fix` to apply the expected identity

Then run gitsignet fix and the right user.name/user.email for that remote are applied for you — no retyping, no copy-paste.

Why

git config includeIf can switch identity — but it keys off the directory the repo lives in, it is silent, and it never stops a bad commit. Clone a work repo into the wrong folder, or forget to set user.email in a fresh clone, and you will happily author commits as the wrong person. You find out when the commit is already pushed with your personal email on a work repo (or your work email on an open-source PR).

gitsignet keys rules off the remote instead of the directory, and it runs as a pre-commit hook that fails the commit when the identity is wrong.

Install

npm install -g gitsignet

Or run it without installing:

npx gitsignet doctor

Quick start

# 1. See what identity you're about to commit as, and why:
gitsignet doctor

# 2. Create a config (writes .gitsignet.json in the repo, or --global):
gitsignet init --global

# 3. Edit the config, then enable the pre-commit guard in a repo:
gitsignet install

Configuration

A .gitsignet.json in the repo overrides a global config at $XDG_CONFIG_HOME/gitsignet/config.json (~/.config/gitsignet/config.json). Keep one global config with all your identities and rules, and you never have to think about it again.

{
  "strict": false,
  "profiles": {
    "work":     { "name": "Work Me",     "email": "[email protected]" },
    "personal": { "name": "Personal Me", "email": "[email protected]" }
  },
  "rules": [
    { "remote": "github.com/acme-*",        "profile": "work" },
    { "remote": "github.com/my-username",    "profile": "personal" },
    { "remote": "gitlab.com/**",             "name": "Personal Me", "email": "[email protected]" }
  ]
}
  • profiles — named identities you can reuse across rules.
  • rules — matched top-to-bottom; the first match wins. Each rule points at a profile, or gives an inline name/email.
  • remote — a glob matched against host/owner/repo, host/owner, and host. * matches within one path segment; ** crosses /. So github.com/acme-* matches a whole org, github.com/acme/widgets a single repo. Use the literal "(none)" to match a repo that has no origin remote at all (a local-only repo). This lets you guard the identity of remoteless repos — for example { "remote": "(none)", "profile": "personal" } — which no host/owner glob can ever match.
  • strict — when true, a commit to a remote that matches no rule is blocked. Off by default (unmatched remotes are allowed).

Commands

| Command | What it does | | --- | --- | | gitsignet doctor [--json] | Explain the identity you're about to commit as, the parsed remote, the matching rule, and whether it's ok. Warns when a later rule is shadowed by an earlier broad one. Never fails a commit. | | gitsignet check [--hook] [--json] | The guard. Exit non-zero on a mismatch / strict violation, or when the identity could not be verified (git missing or failing, unreadable config). --hook stays quiet on success. --json prints the result as JSON. | | gitsignet fix [--global] | Apply the identity the matching rule expects (sets user.name/user.email). --global writes global config. Refuses when no rule matches. | | gitsignet install | Add the gitsignet guard to this repo's pre-commit hook (honours core.hooksPath). Idempotent; preserves an existing hook. | | gitsignet uninstall | Remove the guard from the pre-commit hook. | | gitsignet init [--global] | Write a sample config. |

The installed hook calls gitsignet if it's on PATH, else falls back to npx --no-install gitsignet, so it works whether the tool is installed globally or as a dev dependency. If gitsignet can't be found at all (for example on a fresh clone where nobody installed it), the hook fails open: it prints a one-line notice and lets the commit proceed rather than hard-blocking it.

⚠ The hook needs a real install — npx gitsignet ... is not enough. The pre-commit hook resolves the binary with command -v gitsignet and npx --no-install gitsignet; neither can see packages that only live in the transient npx download cache. If you only ever run gitsignet via npx gitsignet, the hook will fall open (commits pass unchecked). To actually arm the guard, install a resolvable binary:

npm i -g gitsignet     # global — works in every repo
npm i -D gitsignet     # per-project dev dependency

gitsignet install now detects this and prints a loud warning if the hook it just wrote cannot resolve gitsignet.

Exit codes

check and doctor exit 1 on a blocking condition (wrong identity, missing identity, or a strict-mode violation) and 0 otherwise. Unknown commands exit 2.

check also exits 1 when it could not verify the identity: git is not on PATH, git fails for a reason other than "not a git repository" (for example "dubious ownership"), or the config file is not valid JSON. A guard that cannot check must not let the commit through silently. Outside a git repository, check --hook is still a no-op.

How identity is resolved

gitsignet mirrors git's own precedence: GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL environment variables override git config user.name/user.email. That's the identity your next commit will actually carry — which is exactly what gets checked.

License

MIT © flossy-studio