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

quality-scanner

v1.0.8

Published

A unified code quality and security scanning CLI that aggregates results from multiple analysis tools into a single, easy-to-read report

Readme

Quality Scanner

quality-scanner consolidates behavioral scanning, testability analysis, coverage-accountability analysis, security checks, and project quality reporting into one pipeline.

Why this structure

The scanner has separate concerns but one engine:

  • behavior: team engineering practices and project-specific patterns
  • testability: source patterns that create difficult/noisy coverage branches
  • coverage accountability: correlates Istanbul uncovered-branch markers with scanner findings and explicit approved exclusions
  • security: Express endpoint inventory and auth/rate-limit boundary checks
  • quality: combines adjusted coverage, test pass rate, testability, behavior, and security into one project score/report

A concern is not a separate scanner implementation. Rules share the same file discovery, ignore model, scoring, reporting, and CLI.

Run

From this package (or after install):

node index.cjs
npx quality-scanner

Specific gate:

node index.cjs --concern behavior
node index.cjs --concern testability
node index.cjs --concern coverage
node index.cjs --concern security

List rules:

node index.cjs --list-rules

Run without a non-zero quality gate exit code:

node index.cjs --no-fail

Emit a CI-friendly dashboard payload as JSON into a directory:

npx quality-scanner -ci ./quality-scanner-report

You can also point the scanner at an existing coverage artifact directory or file without rerunning test collection. Both Istanbul coverage-summary.json and coverage-final.json files are supported:

npx quality-scanner -ci ./quality-scanner-report -coverage-target="./coverage"

When an explicit coverage target is used and reports/test-results.json is not available, coverage and static scan scores are still reported while the test pass rate is shown as N/A.

Vitest's JSON reporter output at reports/vitest-results.json is also discovered automatically. In a split CI pipeline, preserve both coverage/ and reports/vitest-results.json from the test aggregation job so the quality scan can reuse coverage and test pass/fail counts without rerunning tests.

This writes quality-scanner-report.json containing the same per-concern dashboard payload the HTML report would expose (quality, behavior, testability, and security sections plus their summaries). CI mode suppresses the live test/coverage progress display and emits one final, timestamp-friendly terminal report with quality and coverage bars plus folder/file scan scores. It also emits a GitLab-friendly console pass/fail line and exits with a non-zero code only when the computed releaseConfidence is Blocked.

CI score bars are green at 80% or higher, yellow from 50% through 79.99%, red below 50%, and gray when a score is unavailable. Set NO_COLOR=1 to disable ANSI colors.

The final CI readout also colors release confidence, health, test outcomes, finding counts, coverage-marker counts, release checks, and the GitLab PASS/FAIL status according to their severity.

Reuse today's fresh test/coverage artifacts:

node index.cjs --reuse-artifacts

Recommended package.json scripts

{
  "scripts": {
    "quality:scan": "quality-scanner",
    "quality:scan:behavior": "quality-scanner --concern behavior",
    "quality:scan:testability": "quality-scanner --concern testability",
    "quality:scan:security": "quality-scanner --concern security"
  }
}

For a full quality score, the scanner can collect tests and Istanbul coverage itself via a detected runner (Vitest, Jest, Mocha+nyc, AVA+nyc, or a custom adapter).

Project configuration

Copy quality-scanner.config.example.cjs to the repository root as:

quality-scanner.config.cjs

The example file documents:

  • testablePathPrefixes for narrowing coverage targets
  • behaviorRules for local engineering conventions
  • security publicEndpoints replace vs publicEndpointsExtra append (and the same Extra pattern for middleware patterns)

The most important extension point is behaviorRules:

module.exports = {
  behaviorRules: [
    {
      id: "no-direct-window-location",
      category: "architecture",
      severity: "warning",
      penalty: 8,
      description:
        "Navigation should go through the project navigation boundary.",
      suggestion: "Use the project navigation helper.",
      pattern: /window\.location\s*=/,
    },
  ],
};

That gives each adopting team a way to encode local engineering knowledge without modifying the scanner itself.

Ignore comments

Prefer the modern directive form (targets + reason required):

// quality-scanner-ignore-next-line no-direct-window-location -- intentional for demo
window.location = target;

Multiple targets:

// quality-scanner-ignore-next-line rule-one,rule-two -- Reviewed exception.

Legacy forms still work:

// quality ignore next
someCode();

// behavior ignore next no-direct-window-location
window.location = target;

Use ignores sparingly. They remain visible in source review instead of silently modifying global coverage settings.

Coverage model

The scanner deliberately exposes three different uncovered-branch classifications:

  1. Approved exclusions — actual Istanbul branch markers matching a configured, verified tooling-only exclusion rule. These are removed from adjusted coverage.
  2. Fixable candidates — actual Istanbul branch markers that line up with testability findings such as optional chaining, optional callbacks, ternaries, fallbacks, and default props. They remain in the denominator.
  3. Unclassified markers — uncovered branch markers that are neither approved exclusions nor known fixable candidates. They remain in the denominator and require review.

This prevents the quality score from improving merely because the scanner failed to recognize the cause of an uncovered branch.

Reports

Generated under:

reports/quality-scanner/
  behavior.json
  testability.json
  security.json
  quality.json
  index.html

The HTML dashboard embeds source context for every finding. Clicking a file/line link jumps to the scanned source excerpt with the finding line highlighted.

Unless --no-open is passed, the scanner starts a local Node static server on an ephemeral port and opens the dashboard URL.

The scanner intentionally writes only the current scan. Historical/trend storage is outside the scope of this tool and can be layered on later.

Endpoint security scanning

For JavaScript/TypeScript Express backends, the scanner includes a security concern that inventories static endpoint declarations and looks for missing or incomplete security boundaries.

node index.cjs --concern security

The scanner recognizes common forms including:

app.get("/accounts", requireAuth, handler);
router.post("/applications", requireAuth, handler);
router.use(requireAuth);
router.route("/accounts/:id").get(requireAuth, handler);
app.use("/api", requireAuth, importedRouter);
app.use("/api", requireAuth, require("./routes"));

It currently reports:

  • endpoint-missing-authentication — endpoint has no recognized auth boundary and is not explicitly public
  • object-endpoint-authorization-review — authenticated :id-style resource endpoint where object/function authorization could not be proven
  • authentication-endpoint-missing-rate-limit — login/token/password-style endpoint without a recognized limiter

Security errors are release-blocking independently of the weighted quality score.

Explicit public endpoints

The default public allowlist contains only common health/readiness probes. Other anonymous endpoints should be intentionally declared:

module.exports = {
  security: {
    // Append to defaults:
    publicEndpointsExtra: [
      {
        method: "POST",
        pathPattern: /^\/login$/,
        reason: "Authentication entry point",
      },
    ],
    // Or replace the entire allowlist:
    // publicEndpoints: [ ... ],
  },
};

Declaring an authentication endpoint public does not disable the rate-limit check.

Project-specific security middleware

module.exports = {
  security: {
    authMiddlewarePatternsExtra: [/\brequireSession\b/],
    authorizationMiddlewarePatternsExtra: [/\brequireAccountAccess\b/],
    rateLimitMiddlewarePatternsExtra: [/\bsignInRateLimiter\b/],
  },
};

Patterns are added to the built-in defaults unless you set the non-Extra key to replace them.

What the scanner can and cannot prove

This is static configuration analysis, not a penetration test. It can prove that a recognizable middleware boundary exists in common Express route arrangements, including imported routers mounted behind middleware. It cannot prove that the middleware itself is correct, that handler-level authorization is correct, or that infrastructure outside the source tree is enforcing access control.

Scanner tests

npm test

Package layout

Published files include index.cjs, config.cjs, lib/, rules/, and this README. Requires Node.js 18+.