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

@squiz/validate-pinned-dependencies

v1.0.0

Published

Enforce strict dependency and override version pinning in package.json files across any project or monorepo.

Downloads

189

Readme

@squiz/validate-pinned-dependencies

CI Status NPM Version TypeScript License: MIT

A robust, zero-dependency validation engine to enforce strict dependency and override version pinning in package.json files across any Node.js project or monorepo.


📖 Table of Contents


🛡️ Why Pin Dependencies?

Allowing flexible version ranges (e.g. ^ and ~) in application dependencies introduces non-determinism into your builds. This can lead to:

  1. Unexpected Build Failures: A minor or patch release of a nested third-party library can introduce bugs or breaking changes that break your build without any changes to your code.
  2. Security Vulnerabilities: If a package range is used, an attacker who hijacks a third-party dependency can publish a malicious patch version which is automatically pulled into your production environment.
  3. Harder Debugging: "It works on my machine, but fails in staging/production" is frequently caused by drift in dependencies resolved at different times.

By strictly pinning all third-party dependencies to exact versions (e.g. 1.2.3), you guarantee that every install produces the exact same dependency tree, leading to bulletproof reproducibility and containment.


✨ Features

  • Zero External Dependencies: Built entirely on native Node.js APIs to ensure it is lightweight and lightning-fast.
  • 📂 Recursive Workspace Scanning: Automatically crawls directories to locate and validate all package.json files.
  • ⚙️ Monorepo & Sibling Aware: Smart enough to bypass validation for local workspaces, sibling monorepo packages, or specific organizational scopes (e.g. @squiz/*), allowing them to retain range dependencies for smooth workspace linking.
  • 🔗 Strict Override Validation: Inspects and validates the overrides section of package.json to ensure vulnerability overrides are strictly pinned.
  • 🤝 Peer-Dependency Exempt: Automatically ignores peerDependencies since they define compatibility ranges for host environments and should not be pinned.
  • 🛠️ Configurable & Flexible: Supports exclusion lists (--allow), custom directory ignore paths, and custom internal scope definitions.

📥 Installation

Install the package as a development dependency in your project:

npm install --save-dev @squiz/validate-pinned-dependencies

Or run it directly on-demand using npx:

npx @squiz/validate-pinned-dependencies [options]

💻 CLI Usage

The package exposes a validate-pinned-dependencies executable. Run it with --help to see all configuration parameters:

npx validate-pinned-dependencies --help

Options

| Option | Shorthand | Description | Default | |---|---|---|---| | --dir <path> | -d | The directory to start searching for package.json files | . | | --ignore <dirs> | -i | Comma-separated list of directories to ignore (appends to defaults) | See list below | | --override-ignore <dirs> | | Comma-separated list of directories to ignore (replaces defaults) | None | | --allow <packages> | -a | Comma-separated list of external packages allowed to have ranges | None | | --internal-prefixes <pref>| -p | Comma-separated list of prefixes for internal packages | @squiz/ | | --verbose | -v | Enable detailed logs and display file crawls during validation | false | | --help | -h | Show the help menu and exit | |

Default Ignored Directories

node_modules, cdk.out, build, dist, .git, .changeset, .husky, coverage

Command Examples

1. Basic project-wide verification:

npx validate-pinned-dependencies

2. Target a specific folder and enable verbose logging:

npx validate-pinned-dependencies --dir ./apps --verbose

3. Exempt specific external dependencies that must use ranges:

npx validate-pinned-dependencies --allow react,react-dom

🦊 GitLab CI/CD Integration

To guarantee that no unpinned dependencies make it to your primary branches, integrate the validation check into your GitLab CI pipeline.

Add the following job configuration to your .gitlab-ci.yml (under a test or lint stage):

stages:
  - install
  - test

# ... other configurations ...

validate:pinned-dependencies:
  stage: test
  extends: .setup-node # or whatever node installation anchor/template you use
  interruptible: true
  timeout: 5 minutes
  needs:
    - job: install_dependencies # depends on your install job name
  script:
    - npx @squiz/validate-pinned-dependencies
  allow_failure: false
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "develop"
    - if: $CI_COMMIT_BRANCH == "main"

🐶 Husky / Pre-commit Hook Setup

Catching unpinned dependencies locally before they are pushed to the remote repository ensures a frictionless development loop.

1. Install Husky

If you haven't already set up Husky in your project, install it and initialize:

npm install --save-dev husky
npx husky init

2. Add Pre-Commit Hook

Create or append to your pre-commit hook file (.husky/pre-commit):

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo "🔍 Validating dependency pinning..."
npx @squiz/validate-pinned-dependencies

Make the hook script executable:

chmod +x .husky/pre-commit

Now, every time a developer runs git commit, the validator will check all package.json files and block the commit if any unpinned third-party dependencies are found.


🔧 API Usage (As a Library)

You can import the core validation functions directly into your TypeScript/JavaScript files for custom scripting:

import { validatePackageJson, isPinned, findPackageJsonFiles } from '@squiz/validate-pinned-dependencies';

// Find package.json files
const files = findPackageJsonFiles('./my-project');

// Run individual file checks
const pkgJson = {
  name: 'my-app',
  dependencies: {
    'lodash': '^4.17.21', // unpinned
    'zod': '3.22.4'       // pinned
  }
};
const localPackages = new Set(['my-app', 'my-sibling-lib']);

const errors = validatePackageJson('package.json', pkgJson, localPackages, {
  internalPrefixes: ['@squiz/', '@my-org/'],
  allowRangesFor: ['lodash'] // exempt lodash from being checked
});

if (errors.length > 0) {
  console.log('Errors found:', errors);
} else {
  console.log('Validation passed!');
}

🛠️ Local Development

Prerequisites

  • Node.js >= 18.0.0
  • npm >= 9.0.0

Dev Commands

Install dependencies:

npm install

Run test suite:

npm test

Watch tests during development:

npm run test:watch

Run linter / TypeScript checks:

npm run lint

Auto-format files:

npm run format

Compile TypeScript to JavaScript (dist/ directory):

npm run build

🤝 Contributing

This repository is proprietary and internal to Squiz Group. Contributions and improvements are highly encouraged from any engineer within the company.

Please follow our internal development standards:

1. Branching & Workflows

  • Always branching off of and targeting the develop branch.
  • Create feature branches with descriptive names:
    git checkout -b feat/short-slug develop

2. Code Quality & Standards

  • Keep functions small, modular, and single-responsibility.
  • Document all core logic and public APIs with JSDoc comments.
  • Always add/update unit tests to cover new changes and edge cases.
  • Verify everything compiles, lint checks pass, and tests succeed locally:
    npm run lint && npm test

3. Commit Messages

  • We strictly adhere to Conventional Commits using lowercase formatting:
    • feat(cli): add quiet mode option
    • fix(scanner): resolve crash on null package name
    • test(is-pinned): cover edge cases for beta tags

4. Merge Requests (MR)

  • Push your branch to GitLab and open a Merge Request targeting the develop branch.
  • Standard reviewers for this package are halee, lnowak, trais, and jmatthew.
  • Ensure all CI/CD pipeline checks pass before requesting reviews.

📄 License

Proprietary and Confidential. Copyright (c) 2026 Squiz Group. All Rights Reserved.


Made with ❤️ by Squiz Content Intelligence Team.