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

lockcheck-muin

v1.0.0

Published

Verify lockfile integrity. Detect suspicious registries, duplicate versions, missing hashes.

Readme

lockcheck

npm version License: MIT

Verify lockfile integrity. Detect suspicious registries, duplicate versions, missing hashes.

Why?

Supply chain attacks are real. Lockfiles can contain packages from unexpected registries, missing integrity hashes, or other red flags that automated CI should catch before they hit production.

lockcheck does one thing well: scan your package-lock.json and warn you about potential security issues.

Installation

npm install -g lockcheck

Or run without installing:

npx lockcheck

Usage

# Check current directory
lockcheck

# Check specific file
lockcheck ./path/to/package-lock.json

# Get JSON output
lockcheck --json

# Treat warnings as errors (for CI)
lockcheck --strict

What it checks

  • Suspicious registries - Packages not from registry.npmjs.org or registry.yarnpkg.com
  • Missing integrity hashes - Packages without SHA verification
  • Duplicate versions - Same package with multiple versions (bloats node_modules)

Examples

Example 1: Clean Project - All Good ✅

Scenario: Well-maintained project with standard dependencies.

$ cd my-clean-project
$ lockcheck

🔍 Scanning package-lock.json...

✅ Lockfile looks good!

📊 Summary:
  - Total packages: 342
  - Registries: 1 (registry.npmjs.org)
  - All integrity hashes present: ✓
  - No duplicate versions found: ✓

Exit code: 0

Result: Safe to deploy!


Example 2: Suspicious Registry Detected 🚨

Scenario: A compromised dependency or typosquatting attempt.

$ lockcheck

🔍 Scanning package-lock.json...

⚠️  SECURITY WARNINGS:

🚨 Suspicious Registry:
  - [email protected]
    Expected: https://registry.npmjs.org
    Found:    https://malicious-registry.com/evil-package/-/evil-package-1.0.0.tgz

    ⚠️  This package is NOT from the official npm registry!
    Risk: Supply chain attack, malware injection

🔍 Recommended Action:
  1. Check if this is a private/corporate registry (expected behavior)
  2. If not, REMOVE this package immediately
  3. Run `npm audit` and scan for malware
  4. Notify your security team

Exit code: 1

Action: Investigate and remove the suspicious package.


Example 3: Missing Integrity Hashes

Scenario: Old lockfile or manually edited file missing SHA checksums.

$ lockcheck

🔍 Scanning package-lock.json...

⚠️  MISSING INTEGRITY HASHES:

❌ [email protected] - No integrity hash found
❌ [email protected] - No integrity hash found
❌ [email protected] - No integrity hash found

📊 Summary:
  - Total packages: 89
  - Missing integrity: 3

⚠️  Without integrity hashes, npm cannot verify package contents!
    This allows for man-in-the-middle attacks or corrupted packages.

🔧 Fix:
  rm -rf node_modules package-lock.json
  npm install

Exit code: 1

Example 4: Duplicate Versions Bloating node_modules

Scenario: Different versions of the same package installed, wasting space.

$ lockcheck

🔍 Scanning package-lock.json...

⚠️  DUPLICATE VERSIONS:

📦 lodash found in 3 different versions:
  - 4.17.20 (used by: webpack, babel-core)
  - 4.17.21 (used by: express, mocha)
  - 3.10.1 (used by: legacy-lib)

📦 moment found in 2 different versions:
  - 2.29.1 (used by: react-datepicker)
  - 2.30.0 (used by: chart.js)

📊 Impact:
  - Extra disk space: ~450 KB
  - Potential bugs from version mismatch

💡 Fix:
  npm dedupe  # Attempts to flatten dependency tree
  # Or update dependencies to use consistent versions

Exit code: 0 (warning only)

Example 5: CI Enforcement with --strict Mode

Scenario: Block any lockfile issues in your CI pipeline.

$ lockcheck --strict

🔍 Scanning package-lock.json...

⚠️  Warnings found (treated as errors in --strict mode):

  - Package lodash has 2 different versions: 4.17.20, 4.17.21
  - Package moment has 2 different versions: 2.29.1, 2.30.0

❌ FAILED: 2 warnings in --strict mode

Exit code: 1  ← Build fails

GitHub Actions Example:

- name: Check lockfile
  run: npx lockcheck --strict

Result: PR is blocked until duplicates are resolved.


Example 6: JSON Output for Automation

Scenario: Integrate lockcheck results into your security dashboard.

$ lockcheck --json > lockfile-report.json

Output (lockfile-report.json):

{
  "passed": false,
  "errors": [
    {
      "type": "suspicious_registry",
      "package": "evil-package",
      "version": "1.0.0",
      "registry": "https://malicious-registry.com",
      "expected": "https://registry.npmjs.org"
    }
  ],
  "warnings": [
    {
      "type": "duplicate_version",
      "package": "lodash",
      "versions": ["4.17.20", "4.17.21"]
    }
  ],
  "summary": {
    "totalPackages": 342,
    "registries": [
      "https://registry.npmjs.org",
      "https://malicious-registry.com"
    ],
    "missingIntegrity": 0,
    "duplicates": 1
  }
}

Use case: Parse JSON, send alerts to Slack/PagerDuty if passed: false.

CI Integration

Add to your GitHub Actions workflow:

- name: Check lockfile integrity
  run: npx lockcheck --strict

Exit code is 0 if passed, 1 if errors found. Perfect for blocking bad merges.

API

Use programmatically:

import { checkLockfileFromPath } from 'lockcheck';

const result = checkLockfileFromPath('./package-lock.json', {
  strict: true,
  allowedRegistries: ['https://registry.npmjs.org']
});

if (!result.passed) {
  console.error('Issues found:', result.errors);
}

Options

  • --json - Output results as JSON
  • --strict - Treat warnings as errors (fails with exit code 1)
  • --help - Show help

Real-World Examples

1. CI/CD Security Gate

GitHub Actions:

# .github/workflows/security.yml
name: Security Checks

on:
  push:
    branches: [main]
  pull_request:
    paths:
      - 'package-lock.json'
      - 'yarn.lock'

jobs:
  lockfile-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Verify lockfile integrity
        run: npx lockcheck --strict
      
      - name: Block merge on suspicious packages
        if: failure()
        run: |
          echo "❌ Lockfile contains security issues"
          echo "Review registry sources and missing hashes"
          exit 1

GitLab CI:

# .gitlab-ci.yml
lockfile-audit:
  stage: security
  script:
    - npx lockcheck --strict
  only:
    changes:
      - package-lock.json
  allow_failure: false

2. Pre-commit Hook

Catch lockfile issues before they're committed:

#!/bin/bash
# .git/hooks/pre-commit

if git diff --cached --name-only | grep -q "package-lock.json"; then
  echo "🔍 Checking lockfile integrity..."
  npx lockcheck --strict
  
  if [ $? -ne 0 ]; then
    echo "❌ Lockfile has issues. Fix before committing."
    exit 1
  fi
  
  echo "✅ Lockfile is clean"
fi

With husky:

{
  "husky": {
    "hooks": {
      "pre-commit": "lockcheck --strict"
    }
  }
}

3. Monorepo Scanning

Check all lockfiles in a monorepo:

# Find and check all lockfiles
find . -name "package-lock.json" -not -path "*/node_modules/*" | while read lockfile; do
  echo "Checking $lockfile"
  lockcheck "$lockfile" --strict
done

# Or with parallel processing
find . -name "package-lock.json" -not -path "*/node_modules/*" | \
  parallel lockcheck {} --strict

4. Custom Registry Whitelist

For organizations using private registries:

# Allow specific registries (feature request - example config)
# lockcheck.config.json
{
  "allowedRegistries": [
    "https://registry.npmjs.org",
    "https://npm.internal.company.com",
    "https://artifacts.company.io"
  ],
  "strict": true
}

# Then run
lockcheck --config lockcheck.config.json

5. Automated Dependency Updates

Combine with Dependabot or Renovate:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    reviewers:
      - "security-team"
    # After Dependabot creates PR, lockcheck runs automatically

GitHub Action to verify Dependabot PRs:

name: Verify Dependency Updates

on:
  pull_request:
    branches: [main]

jobs:
  check-deps:
    if: github.actor == 'dependabot[bot]'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Verify lockfile
        run: npx lockcheck --strict
      
      - name: Auto-merge if safe
        if: success()
        run: gh pr merge --auto --squash ${{ github.event.pull_request.number }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

6. JSON Output for Reporting

Generate security reports:

# Generate JSON report
lockcheck --json > lockfile-report.json

# Parse with jq
lockcheck --json | jq '.errors'

# Count issues
lockcheck --json | jq '.errors | length'

# Alert if issues found
lockcheck --json | jq -e '.passed == false' && \
  curl -X POST https://alerts.company.com/webhook \
  -d "Lockfile security issues detected"

7. Periodic Security Audits

Weekly lockfile health checks:

# crontab
0 9 * * 1 cd /path/to/project && lockcheck --json > reports/lockcheck-$(date +\%Y\%m\%d).json

# GitHub Actions scheduled scan
# .github/workflows/weekly-audit.yml
name: Weekly Security Audit

on:
  schedule:
    - cron: '0 9 * * 1'  # Every Monday at 9 AM

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Run lockfile check
        run: lockcheck --json > lockcheck-report.json
      
      - name: Upload report
        uses: actions/upload-artifact@v3
        with:
          name: lockfile-audit
          path: lockcheck-report.json
      
      - name: Notify on Slack if issues
        if: failure()
        run: |
          curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
          -d '{"text":"⚠️ Weekly lockfile audit found issues"}'

8. Emergency Response

When a supply chain attack is detected:

# Quick scan across all projects
for repo in ~/projects/*/; do
  if [ -f "$repo/package-lock.json" ]; then
    echo "Scanning $repo"
    lockcheck "$repo/package-lock.json" --strict || echo "⚠️  Issue in $repo"
  fi
done

# Generate org-wide report
for repo in ~/projects/*/; do
  if [ -f "$repo/package-lock.json" ]; then
    echo "$repo" >> org-report.txt
    lockcheck "$repo/package-lock.json" --json >> org-report.txt
  fi
done

Contributing

PRs welcome. Keep it simple.

  1. Fork the repo
  2. Create a feature branch
  3. Add tests for new features
  4. Run npm test
  5. Submit PR

License

MIT