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

pseo-quality-gate

v0.1.0

Published

Premium-content quality gate for programmatic SEO at scale. 13 hard gates that distinguish premium pSEO content from AI-slop templates.

Readme

pseo-quality-gate

Premium-content quality gate for programmatic SEO at scale. Thirteen hard gates that distinguish premium pSEO content from the AI-slop templates that get classified out of Google's index.

License: MIT Node Zero dependencies

The problem

Programmatic SEO operations that ship at scale (>100 pages from a single template) face a specific Google failure mode. The helpful-content classifier waits two to twelve weeks before applying a site-wide quality verdict, and once it triggers, the entire programmatic surface drops out of the index together. Individual page recovery after a site-level demotion takes months and sometimes never happens.

The Detailed.com 2024 audit of 23 large affiliate sites found that 17 had lost 60-95% of organic traffic within 90 days of a major Google update. The surviving 6 had measurably stricter content quality controls in place pre-update.

Writing better content is the standard advice. Enforcing "better" mechanically before pages ship, at the scale where humans cannot review every page individually, is the hard part.

What this package does

Validates a JSON content payload against thirteen hard gates that approximate the helpful-content classifier's filter from the public side. The gates are necessary, not sufficient. Passing every gate does not guarantee ranking; failing any gate is a strong predictor of eventual deindexation.

The validator is content-generator-agnostic. It fires on the output of whatever pipeline you use (human, LLM, hybrid) and tells you whether the page passes the structural and stylistic gates. It does not generate content, score backlinks, or validate schema.org markup; those are separate concerns with their own tools.

Quick start

# Run via npx, no install required
npx pseo-quality-gate ./content/page-001.json

# Validate a directory tree
npx pseo-quality-gate --glob "content/**/*.json"

# Machine-readable output for CI pipelines
npx pseo-quality-gate --json ./content/page-001.json

Or as a library:

import { runAllGates } from "pseo-quality-gate";
import fs from "fs";

const data = JSON.parse(fs.readFileSync("page.json", "utf8"));
const result = runAllGates(data);

if (!result.pass) {
  for (const e of result.errors) console.error(`${e.gate}: ${e.message}`);
  process.exit(1);
}

The thirteen gates

| # | Gate | What it checks | |---|---|---| | 1 | title | length ≤ 70 chars | | 2 | metaDescription | length 130-165 chars | | 3 | h1 | present | | 4 | about | ≥ 4 paragraphs, ≥ 500 words total | | 5 | faqs | ≥ 5 items, each answer ≥ 15 words | | 6 | citations | ≥ 1 with valid reference id (when embeddedItems[] is non-empty) | | 7 | relatedLinks | ≥ 5 internal links | | 8 | author | name and url present | | 9 | lastUpdated | YYYY-MM-DD format | | 10 | emDashes | zero anywhere in the JSON | | 11 | marketingProse | no blocklisted terms in body content | | 12 | marketingHeadlines | no blocklisted terms in title/h1/subheading/metaDescription | | 13 | solicitCriticism | no fake-humility closers anywhere |

Full gate-by-gate reference: docs/13-hard-gates.md.

Schema

The validator works on a generic premium-content shape. Map your domain fields to this shape; the gates do not require any specific vertical.

interface PremiumContentPage {
  title: string;            // <= 70 chars
  metaDescription: string;  // 130-165 chars
  h1: string;
  subheading?: string;
  about: string[];          // >= 4 paragraphs, >= 500 words total
  faqs: { q: string; a: string }[];               // >= 5
  citations?: { id: string; text: string }[];     // required if embeddedItems[]
  embeddedItems?: { id: string; [k: string]: any }[];
  relatedLinks: { url: string; label: string }[]; // >= 5
  author: { name: string; url: string };
  lastUpdated: string;      // YYYY-MM-DD
}

See examples/pass.json for a complete passing payload and examples/fail.json for a deliberately broken one.

Configuring thresholds

import { runAllGates, DEFAULT_THRESHOLDS } from "pseo-quality-gate";

const result = runAllGates(data, {
  thresholds: {
    ...DEFAULT_THRESHOLDS,
    ABOUT_MIN_WORDS: 750,    // stricter than default 500
    FAQ_MIN: 7,              // stricter than default 5
  },
  extraProseTerms: ["unrivaled", "world-renowned"],   // extend the blocklist
});

Using individual gates

import { gateAbout, gateMarketingProse, gateEmDashes } from "pseo-quality-gate/gates";

const errors = [
  gateAbout(data),
  gateEmDashes(data),
  gateMarketingProse(data, { extraProseTerms: ["myextra"] }),
].filter(Boolean);

Origin

This validator was originally written for the day-trip programmatic SEO section of bestroadtrip.com, where it gates eighty city-pair pages built from a corpus of 1,400 creator-recorded short videos. The site's research section publishes the underlying methodology and dataset behind the page generator; the gates here are extracted from that specific operation and generalized for any premium pSEO content type.

Security and privacy

This package is a CLI/library that reads local JSON files and runs deterministic checks. It makes zero outbound network requests. It uses zero npm dependencies. It does not collect telemetry, write to any path outside the working directory it is run in, or contain any embedded credentials, API keys, or proprietary data. The validator can be run fully offline against any content payload.

Contributing

Contributions welcome. New gates that have empirical backing, refinements to the default thresholds, or expansions to the marketing-language blocklist are all in scope. See CONTRIBUTING.md.

License

MIT. See LICENSE.