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

doc-freshness-checker

v1.2.2

Published

Universal documentation freshness checker - validates documentation accuracy against actual codebase

Readme

Documentation Freshness Checker

npm version npm downloads License: MIT Node.js CI

Validate documentation against your codebase to catch stale references before they create confusion or slow onboarding. doc-freshness-checker scans your docs, extracts references to files, URLs, versions, symbols, dependencies, and directory trees, then validates each one against source code and manifests.

Table of Contents

Why Use It

  • Reduce drift between docs and implementation.
  • Catch broken file links and dead external URLs.
  • Detect version mismatches between docs and manifests.
  • Surface code symbols mentioned in docs that no longer exist.
  • Detect stale code examples — wrong imports, changed function signatures, outdated config keys.
  • Run in CI as a quality gate or reporting step.

Features

  • Documentation formats: Markdown (.md, .markdown), reStructuredText (.rst), AsciiDoc (.adoc, .asciidoc), plaintext (.txt).
  • Source indexing for symbol validation: JavaScript, TypeScript, Python, Go, Rust, Java.
  • Code snippet validation: verifies import paths resolve, imported symbols are exported, function call signatures still match example placeholders, and config object keys match type/interface definitions.
  • Manifest parsing for version/dependency checks: package.json, requirements.txt, pyproject.toml, go.mod, Cargo.toml, pom.xml.
  • Reporters: console, json, markdown, enhanced.
  • Advanced modes: incremental checking, freshness scoring, graph linking, semantic vector search.

Prerequisites

  • Node.js >= 22.19.0
  • npm

Installation

npm install --save-dev doc-freshness-checker

Global installation is also supported:

npm install -g doc-freshness-checker

Quick Start

Run with defaults (checks docs/**/*.md and README.md):

doc-freshness

Example console output:

📚 Documentation Freshness Report

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📊 Summary:
   Total references checked: 42
   ✅ Valid: 38
   ❌ Errors: 2
   ⚠️  Warnings: 2
   ⏭️  Skipped: 0

📋 Issues by Document:

📄 docs/getting-started.md
────────────────────────────────────────
  ❌ Line 14: File not found: src/old-module.ts
     💡 File may have been moved or renamed
  ⚠️  Line 27: Version mismatch: docs say 2.1.0, package.json has 3.0.0

📄 README.md
────────────────────────────────────────
  ❌ Line 45: Broken URL: https://example.com/dead-link (404)
  ⚠️  Line 82: Symbol not found in source: calculateTotal()
     💡 Symbol may have been renamed or removed

Create a minimal config:

// .doc-freshness.config.js
export default {
  include: ['docs/**/*.md', 'README.md'],
  exclude: ['**/node_modules/**'],
};

Generate a Markdown report file:

doc-freshness --reporter markdown --output .doc-freshness-reports/report.md

CLI Reference

doc-freshness [options]

Options:
  -c, --config <path>     Path to config file
  -r, --reporter <type>   Reporter type (console, json, markdown, enhanced)
  -o, --output <path>     Output file path for reports
  -v, --verbose           Enable verbose logging
  --only <types>          Only check specific reference types (comma-separated)
  --skip-urls             Skip URL validation
  --files <patterns>      Only check specific files (comma-separated glob patterns)
  --manifest <files>      Manifest files to use (comma-separated)
  --source <patterns>     Source patterns to use (comma-separated)
  --no-cache              Disable caching
  --clear-cache           Clear cache before running
  --score                 Include freshness scores in report
  --incremental           Only check changed files (requires cache)
  --vector-search         Enable semantic vector search for doc-code mismatches

Common Examples

# Basic scan
doc-freshness

# JSON report file
doc-freshness --reporter json --output reports/doc-freshness.json

# Faster run when network checks are not needed
doc-freshness --skip-urls

# Restrict to selected files
doc-freshness --files "README.md,docs/usage.md"

# Enable scoring and incremental mode
doc-freshness --score --incremental

Exit Codes

  • 0: no validation errors
  • 1: at least one validation error, or runtime/config failure

What Gets Validated

| Reference type | What is checked | | --------------------- | --------------------------------------------------------------------------------- | | file-path | Referenced files/directories exist | | external-url | External URLs are reachable (with caching and skip rules) | | version | Mentioned versions compared to parsed manifests | | directory-structure | Tree snippets align with actual structure | | code-pattern | Mentioned symbols exist in indexed source | | code-snippet | Import paths resolve, exported symbols exist, function signatures still match, config keys valid | | dependency | Mentioned packages exist in manifest dependencies |

URL Validation Behavior

  • Deduplicates repeated URLs per run.
  • Skips template-like URLs with placeholders.
  • Supports skip domains (defaults include localhost, 127.0.0.1, example.com).
  • Treats auth-required responses (401/403) as valid-with-note.
  • Handles GitHub 404 private-repo behavior conservatively.
  • Caches URL results to reduce repeated checks.

Code Snippet Validation

Fenced code blocks in documentation go stale just as quickly as any other reference. The code-snippet rule validates three aspects of code examples:

Import statements — verifies that the module path resolves to an actual source file and that each imported symbol is exported from it. Only relative imports are checked; bare npm/package imports are skipped.

If your docs contain:

```typescript
import { createUser, sendWelcomeEmail } from './services/userService';
```

The checker resolves ./services/userService against the project source tree (trying common extensions and index files) and confirms that createUser and sendWelcomeEmail are exported. If sendWelcomeEmail was renamed to sendOnboardingEmail, the report shows:

⚠️  Line 12: Symbol(s) not exported from src/services/userService.ts: sendWelcomeEmail
   💡 Did you mean: sendOnboardingEmail?

Function signatures — checks that the number of arguments shown in a code example matches the function's current signature, accounting for optional and rest parameters. When an example uses simple placeholder identifiers like name, email, those are also compared to the current parameter names to catch renamed positional parameters.

```typescript
const user = createUser(name, email, role, department);
```

If createUser now takes only (name, email, role?), the report shows:

⚠️  Line 18: Function createUser called with 4 arg(s) but expects 2–3
   💡 Current signature: createUser(name, email, role)

Config object keys — when a code example assigns an object with an explicit type annotation, each key is checked against the type/interface definition in source.

```typescript
const opts: ServerConfig = {
  port: 3000,
  hostname: 'localhost',
  maxRetries: 5,
};
```

If ServerConfig no longer has a hostname property (renamed to host):

⚠️  Line 24: Config key(s) not found in ServerConfig: hostname
   💡 Did you mean: hostname → host?

Each sub-check can be toggled independently:

rules: {
  'code-snippet': {
    enabled: true,
    severity: 'warning',
    validateImports: true,
    validateFunctionCalls: true,
    validateConfigKeys: true,
  },
},

False Positive Reduction

Illustrative paths and symbols (e.g., tutorial placeholders) are detected automatically and can be skipped or downgraded in severity via rule configuration.

Configuration

Auto-Discovery

When --config is not provided, the loader checks these names in project root:

  • .doc-freshness.config.js
  • .doc-freshness.config.json
  • doc-freshness.config.js
  • doc-freshness.config.json

Explicit Config Path

With --config, the loader supports .json, .cjs, and JS/ESM config files.

Type-Safe Config

Use defineConfig for better editor inference:

import { defineConfig } from 'doc-freshness-checker';

export default defineConfig({
  include: ['docs/**/*.md', 'README.md'],
  rules: {
    'file-path': { enabled: true, severity: 'error' },
    'external-url': { enabled: true, severity: 'warning' },
  },
});
/** @type {import('doc-freshness-checker').DocFreshnessConfig} */
export default {
  rootDir: process.cwd(),
  include: ['docs/**/*.md', 'README.md'],
  exclude: ['**/node_modules/**', '**/dist/**'],

  // Optional: auto-detected when null/omitted
  manifestFiles: null,
  sourcePatterns: null,

  urlValidation: {
    enabled: true,
    timeout: 10000,
    concurrency: 5,
    skipDomains: ['localhost', '127.0.0.1', 'example.com'],
    cacheSeconds: 3600,
  },

  rules: {
    'file-path': { enabled: true, severity: 'error' },
    'external-url': { enabled: true, severity: 'warning' },
    version: { enabled: true, severity: 'warning' },
    'directory-structure': { enabled: true, severity: 'warning' },
    'code-pattern': { enabled: true, severity: 'warning' },
    'code-snippet': { enabled: true, severity: 'warning' },
    dependency: { enabled: true, severity: 'info' },
  },

  reporters: ['console'],
  cache: { enabled: true, dir: '.doc-freshness-cache', maxAge: 86400000 },
  incremental: { enabled: false },
  vectorSearch: { enabled: false, similarityThreshold: 0.3 },
  verbose: false,
};

For details on CLI-to-config mapping and precedence, see CLI and Configuration Precedence. For the internal execution pipeline, see Runtime Architecture.

CI Integration

This repository includes a GitHub Actions workflow at .github/workflows/doc-freshness.yml for a working example.

Minimal CI command:

npx doc-freshness --reporter markdown --output .doc-freshness-reports/report.md

The same command works in GitHub Actions, GitLab CI, CircleCI, and other CI systems.

Programmatic API

import { loadConfig, run } from 'doc-freshness-checker';

const config = await loadConfig();
const results = await run(config);

console.log(results.summary);

Key exports:

| Export | Purpose | | ------------------------------------------------------------------------- | ---------------------------------------------------- | | run, runWithConfig | Execute the checker programmatically | | loadConfig, defineConfig | Load/merge configuration and type-safe config helper | | DocumentParser | Parse documentation files and extract references | | CodeSnippetExtractor, CodeSnippetValidator | Code example validation (imports, calls, config) | | ValidationEngine | Dispatch references to validators | | ConsoleReporter, JsonReporter, MarkdownReporter, EnhancedReporter | Reporter classes | | GraphBuilder, FreshnessScorer, VectorSearch | Advanced analysis modules | | DocFreshnessConfig, ValidationResults | Core types |

Contributing

Contributions are welcome. See CONTRIBUTING.md for setup instructions, development workflow, and PR guidelines.

Acknowledgments

  • Commander.js — CLI argument parsing
  • glob — File pattern matching
  • semver — Semantic version parsing and comparison
  • FastEmbed — Local embedding generation for semantic checks

License

MIT License — see LICENSE for details.