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 🙏

© 2025 – Pkg Stats / Ryan Hefner

hookguard

v1.1.16

Published

HookGuard is a powerful developer tool designed to detect unsafe, complex, or undocumented behaviors in React hooks — both built-in and custom. It helps teams maintain scalable, clean, and predictable component logic by uncovering patterns that often lead

Readme

🧠 HookGuard — Auditing Hook Behavior in React Codebases

HookGuard is a powerful developer tool designed to detect unsafe, complex, or undocumented behaviors in React hooks — both built-in and custom. It helps teams maintain scalable, clean, and predictable component logic by uncovering patterns that often lead to bugs, performance issues, or architectural rot.

You can learn more about HookGuard in this blog post.

HookGuard

🚀 Project Objective

Goal: Provide visibility and control over the complexity of React components and hooks.
HookGuard identifies:

  • Hooks with uncleaned side effects ✅
  • Repeated, nested, or coupled network ✅
  • Shared logic with hidden state dependencies ⚙️
  • Custom hooks doing more than advertised ⚙️
  • Inconsistent or conditional hook usage ⚙️

🛠️ CI/CD Integration

🤖 GitHub Action

Create a file named .github/workflows/hookguard.yml with the following contents:

name: HookGuard Routine

on:
  pull_request:
    paths:
      - "src/**"
      - "**.ts"
      - "**.tsx"

jobs:
  scan:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install dependencies
        run: |
          corepack enable
          npm install
          npm run build

      - name: Generate report from master
        run: |
          git fetch origin master
          git reset --hard  # ← supprime les fichiers modifiés
          git switch -c master-snapshot FETCH_HEAD
          npx hookguard scan ./src
          mv $(ls -t ./data/hookguard-log-*.json | head -n1) ./data/hookguard-master.json

      - name: Restore PR branch
        run: |
          git checkout ${{ github.head_ref }}

      - name: HookGuard Scan on PR
        run: |
          npx hookguard scan ./src
          mv $(ls -t ./data/hookguard-log-*.json | head -n1) ./data/hookguard-pr.json

      - name: Generate HookGuard summary (Markdown)
        run: |
          HG_MARKDOWN=1 npx hookguard report ./data/hookguard-pr.json > hookguard-summary.md

      - name: Comment HookGuard summary on PR
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          path: hookguard-summary.md
          header: hookguard-summary

      - name: Generate HookGuard diff
        run: |
          npx hookguard diff ./data/hookguard-master.json ./data/hookguard-pr.json > hookguard-diff.md

      - name: Comment HookGuard diff on PR
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          path: hookguard-diff.md
          header: hookguard-diff

If you don't want to comment on the PR you can remove the corresponding step.

🚀 Usage

Run hookguard scan <directory> to scan a directory recursively for hooks.

Run hookguard report <reportFile> to print a summary of the scan results.

🎛️ Configuration – hookguard.config.ts

You can customize HookGuard's behavior by creating a hookguard.config.ts file in the root of your project.

Use hookguard init . to generate a default configuration file.

This configuration file allows you to:

  • Enable or disable specific rules
  • Set thresholds to fail CI on certain risk conditions
  • Define custom suspicious calls to track (e.g. setSession, setGlobalState)

🧪 Example

// hookguard.config.ts
import { HookRule, RuleResult } from "./src/rules/Rule";
import { HookInfo } from "./src/scanner/hookExtractor";
import { HookGuardConfig } from "./src/config/defaultConfig";

/**
 * Fake rule for demonstration purposes
 */
export class FakeRule implements HookRule {
  id = "fake-rule";
  description = "It's a fake rule for demonstration purposes";

  appliesTo(hook: HookInfo): boolean {
    return hook.name === "useEffect";
  }

  evaluate(hook: HookInfo): RuleResult | null {
    return {
      ruleId: this.id,
      level: "info",
      message: "It's a useEffect hook!",
      suggestions: [
        "Write here some suggestions for ensuring the rules is respected",
      ],
    };
  }
}

export const config: HookGuardConfig = {
  customRules: { "fake-rule": new FakeRule() },
  rules: {
    "no-cleanup": true,
    "unsafe-network": true,
    "excessive-dependencies": true,
    "missing-dependency": false,
    "async-effect": false,
    "fake-rule": true,
  },
  thresholds: {
    failOnScore: undefined,
    failOnCritical: false,
  },
  suspiciousCalls: [
    "setUser",
    "setAuth",
    "setSession",
    "setTheme",
    "setLocale",
    "setLanguage",
    "setSettings",
  ],
};

If the file is missing or invalid, HookGuard will fall back to default configuration. You can create your own set of rules by creating new classes that implement the HookRule interface. Don't forget to add them to the customRules and rules objects in the configuration file.

Rules Details

🧠 Rule: missing-dependency

Detects when variables used inside the callback of a React hook (useEffect, useCallback, useMemo, etc.) are missing from the dependency array.

✅ Example

useEffect(() => {
  fetchData(query);
  console.log(user.name);
}, []);

➡️ Will raise:
Missing dependencies: query, user


Known global objects (e.g. console, Promise, Math, setTimeout, etc.) are ignored.


🧱 Global Identifier Filtering

To avoid false positives, HookGuard uses a built-in IGNORED_GLOBALS set — a comprehensive list of browser and Node.js globals (e.g. window, Promise, JSON, etc.).

You can see it in src/utils/globals.ts.

📅 Development Timeline

🧪 Day 1: MVP & Core Engine

  • [x] CLI to scan a codebase: hookguard scan ./src
  • [x] File discovery (.ts, .tsx, .js, .jsx)
  • [x] AST parsing (using ts-morph)
  • [x] Detection of:
    • useEffect, useMemo, useCallback
    • Custom hooks (use*)
  • [x] Extraction of:
    • Hook name, dependencies, contents
    • Network calls (fetch, axios, etc.)
    • Global state updates
    • Cleanup function presence
  • [x] JSON report output

🧠 Day 2–3: Rule Engine & Scoring System

  • [x] Modular rule engine (Chain of Responsibility)
  • [x] Detection rules:
    • Missing cleanup
    • Conditioned hook execution
    • Unsafe network call without cancellation
    • Excessive setState or context mutation
  • [x] Risk scoring system per hook
  • [x] Summary dashboard per file/component

🔁 Day 4: CI / Git Integration

  • [x] GitHub Action: run HookGuard on PRs
  • [x] PR comment with summary of risks
  • [x] Risk diffing: new vs. resolved hook issues
  • [x] Badge for "clean hooks"
  • [x] Config file support (hookguard.config.ts)

(Optional backend/database integration to persist reports per branch or commit, store diffs and long-term analytics)

💡 Week 2: IntelliSense & On-the-fly Detection

  • [ ] VS Code extension (or Language Server) to:
    • Highlight risky hook usage as you type
    • Auto-suggest cleanup patterns
    • Provide tooltip summaries for custom hooks
  • [ ] Panel to display all faulty hooks in the project

(Requires bundling a local lightweight engine or pre-built ruleset into the extension)

🖼️ Week 3: UI & Visualization Layer

  • [ ] React web UI for browsing reports
  • [ ] Hook graph: links between components and state
  • [ ] Filtering by severity, module, team
  • [ ] Export to Notion/Markdown/CSV
  • [ ] Caching layer (Redis or local FS-based) for fast reloads and diff views
  • [ ] Self-hosted UI dashboard (Docker-ready)

(Requires lightweight backend API to serve cache and persistent report data)

📊 Week 4: Insights & Intelligence

  • [ ] Time-based tracking of risk accumulation
  • [ ] Suggested refactor targets (e.g. extract effect)
  • [ ] Historical snapshots per branch or tag
  • [ ] Visualization of "hot files"
  • [ ] LLM-assisted refactoring suggestion

(Requires lightweight database or file-backed store for snapshots)


🧱 Core Architecture

  • CLI: Entry point, options parser
  • Scanner: File system + AST parser
  • HookNode: Internal model (hook metadata + diagnostics)
  • Rule Engine: Modular rule executor
  • Report Formatter: JSON builders
  • UI Frontend: Report visualizer (optional)
  • Cache: File-based or Redis-backed for fast repeated analysis
  • Extension SDK: For LSP or IDE plugins

✅ Use Cases

  • Audit a codebase before major refactor
  • Enforce hook hygiene in a growing team
  • Assist onboarding by highlighting complex logic
  • Justify architectural changes with risk metrics
  • Detect dangerous patterns in-flight (with IDE integration)

👥 Target Users

  • React developers
  • Tech leads & Staff Engineers
  • Architects auditing app complexity
  • QA / DevEx teams supporting frontend teams

📎 License & Contribution

MIT


Created by: quack
Purpose: Reveal what’s hidden in React logic — before it hurts you in production.