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

@cleartrip/frontguard

v1.0.1

Published

Frontend PR guardrails — lint, type safety, secrets, bundle size, PR hygiene, and more. Runs in CI and posts a report comment on every pull request.

Readme

FrontGuard

Automated frontend code quality checks for every pull request. Runs in CI, catches issues before merge, and posts a clean report comment with a link to the full interactive HTML report.


What it checks

| Check | What it does | Runs on | |:------|:------------|:--------| | eslint | Linting with your project's ESLint config | Changed files | | prettier | Formatting check against your Prettier config | Changed files | | typescript | tsc --noEmit type checking | Whole project | | secrets | Regex scan for leaked tokens, keys, private keys | Changed files | | pr-hygiene | PR description length, required sections, AI disclosure | PR metadata | | pr-size | Flags PRs that are too large to review effectively | PR diff | | ts-any-delta | Counts new any usage introduced in this diff | PR diff | | cycles | Circular import detection via madge | Source tree | | dead-code | Unused exports via ts-prune | Whole project | | bundle | Bundle size measured after build, compared to a baseline | Build output | | core-web-vitals | Static JSX/TSX hints for LCP, CLS, FID patterns | Changed files | | react-native | Metro config, SwiftLint, native file hints (RN projects only) | Changed files | | custom-rules | Your own file/content checks defined in config | Changed files | | ai-assisted-strict | Stricter checks on AI-generated code regions | Opt-in |

All checks are enabled by default except ai-assisted-strict and llm (both off by default). Every check can be disabled or tuned individually.


Quick start

1. Install

npm install -D @cleartrip/frontguard
# or
yarn add -D @cleartrip/frontguard
# or
pnpm add -D @cleartrip/frontguard

2. Initialise

npx frontguard init

This creates three files:

  • frontguard.config.mjs — config file with every option documented as comments
  • pull_request_template.md — PR template with AI disclosure checkboxes
  • bitbucket-pipelines.yml — creates or updates the pipeline with a FrontGuard step

3. Run locally

npx frontguard run

Run the same checks locally before pushing. No CI environment needed.


Configuration

Config lives in frontguard.config.mjs (recommended), frontguard.config.cjs, or frontguard.config.js at your project root.

// frontguard.config.mjs
import { defineConfig } from '@cleartrip/frontguard'

export default defineConfig({
  // 'warn'    = advisory only, CI never fails (default)
  // 'enforce' = CI exits non-zero on any block-severity finding
  mode: 'warn',

  checks: {
    // Tune any check by key — only set what you want to override
    prSize: {
      tiers: [
        { minLines: 800,  severity: 'block', message: 'PR too large (${lines} lines). Split it up.' },
        { minLines: 400,  severity: 'warn',  message: 'Large PR (${lines} lines). Consider splitting.' },
      ],
    },
    bundle: {
      buildCommand: 'yarn build',
      maxDeltaBytes: 50_000,   // fail if bundle grows more than 50 kB
    },
    // Disable a check entirely
    deadCode: { enabled: false },
    // Custom rules — plain JS functions
    // (see Custom rules section below)
  },
})

Run frontguard init to generate the full annotated template.

Severity levels

| Level | Meaning | |:------|:--------| | info | Informational note — never fails CI | | warn | Advisory — visible in report, CI passes unless mode: 'enforce' | | block | Failing — CI exits non-zero when mode: 'enforce' is set |

Gate modes

Most checks have a gate option that controls the severity of their findings:

cycles: { gate: 'block' }    // circular deps now fail CI in enforce mode
tsAnyDelta: { gate: 'warn' } // any usage is advisory (default)

Custom rules

Define your own checks inline in the config file. The function receives { path, content } for each file and returns true when the rule is violated.

export default defineConfig({
  rules: {
    'no-console-log': {
      severity: 'warn',
      message: 'Remove console.log before merging',
      check: (file) =>
        /\.(ts|tsx|js|jsx)$/.test(file.path) && /console\.log\(/.test(file.content),
    },
    'no-todo-comments': {
      severity: 'info',
      message: 'Unresolved TODO comment',
      check: (file) => /\bTODO\b/.test(file.content),
    },
    'no-inline-styles': {
      severity: 'info',
      message: 'Prefer CSS classes over inline style objects',
      check: (file) => /\.tsx$/.test(file.path) && file.content.includes('style={{'),
    },
  },
})

Bundle size

The bundle check builds your project and compares the output size against a baseline file you commit to your repo.

Setup

  1. Run your build once and create the baseline:

    echo '{ "totalBytes": 245760 }' > .frontguard/bundle-baseline.json
    git add .frontguard/bundle-baseline.json
  2. Configure the check:

    bundle: {
      buildCommand: 'yarn build',
      maxDeltaBytes: 50_000,   // warn/block if bundle grows > 50 kB
      maxTotalBytes: null,     // or set an absolute cap
    }
  3. FrontGuard reads the baseline from baselineRef (default: main) when the file is not on disk, so it works in PR pipelines automatically.

Size strategies

| Strategy | Use when | |:---------|:---------| | auto | Most projects — auto-detects Next.js, Vite, CRA, or falls back to glob | | next | Next.js — reads "First Load JS shared by all" from build output | | vite | Vite — sums dist/assets/*.js | | cra | Create React App — reads gzipped JS total from build output | | glob | Custom build tools — sums files matching measureGlobs | | custom | Anything else — runs bundleSizeCommand, reads bytes from stdout |


PR hygiene

Validates the PR description when running in CI (requires FRONTGUARD_PR_BODY env var):

prHygiene: {
  minBodyLength: 80,           // minimum characters in description
  requireSections: true,       // require headers from sectionHints
  sectionHints: ['what', 'why', 'test', 'screenshot'],
  requireAiDisclosureSection: true,  // expect an ## AI disclosure section
}

The pull_request_template.md created by frontguard init includes the AI disclosure section automatically.


Shared org config

Publish defaults to an npm package and extend them in each repo:

// frontguard.config.mjs
export default defineConfig({
  extends: '@your-org/frontguard-config',
  checks: {
    // repo-specific overrides
  },
})

The org config is deep-merged as a base layer. Individual repos only need to set what differs.


CLI reference

# Scaffold config, PR template, and pipeline step
frontguard init

# Run all checks (console output + markdown report)
frontguard run

# Fail CI on block-severity findings
frontguard run --enforce

# Output markdown only (good for capturing in CI logs)
frontguard run --markdown

# Generate HTML report file
frontguard run --htmlOut report.html

# Generate Bitbucket PR comment markdown
frontguard run --prCommentOut comment.md

# Append manual review notes to the report
frontguard run --append ./notes.md

CI integration (Bitbucket)

frontguard init creates or updates bitbucket-pipelines.yml with a ready-to-use step. It:

  1. Runs all checks
  2. Generates an HTML report
  3. Uploads it to FreeKit (static hosting, free, no login)
  4. Posts a comment on the PR with the risk score and a link to the full report

Required variables

Add these as secured variables in your Bitbucket repo settings:

| Variable | Required | Purpose | |:---------|:---------|:--------| | BITBUCKET_ACCESS_TOKEN | Yes | Post PR comments | | FREEKIT_BASE_URL | No | Override report hosting (default: https://freekit.dev) | | FRONTGUARD_PR_BODY | No | Pass PR description to pr-hygiene check |

Pipeline init scenarios

| Situation | What init does | |:----------|:----------------| | No bitbucket-pipelines.yml | Creates one with image, clone, and the FrontGuard step | | File exists, no pull-requests: section | Appends a pull-requests: section | | File exists, pull-requests: present | Appends the FrontGuard step after existing steps | | FrontGuard step already present | Skips (no duplicates) |

Your image, clone, definitions, and other pipeline config are never modified.


Risk scoring

The risk score is a heuristic shown at the top of every report.

| Score | When | |:------|:-----| | 🔴 HIGH | 1+ blocking findings, or 8+ warnings, or 800+ changed lines | | 🟡 MEDIUM | 3–7 warnings, or 400–799 changed lines, or 25+ files changed | | 🟢 LOW | No significant findings |

The score is informational — it does not affect CI pass/fail by itself.


React Native

The react-native check runs automatically when react-native is in your dependencies.

| Sub-check | Default | What it does | |:----------|:--------|:-------------| | Metro config | On | Warns if metro.config.* is missing | | SwiftLint | On | Runs swiftlint when PR touches .swift files | | Android hint | On | Reminds to run Android Lint when .kt/.java change | | @rnx-kit/align-deps | Off | Validates RN dependency alignment (opt-in, needs network) | | react-native doctor | Off | Runs the RN doctor CLI (opt-in, slow) |


AI-assisted review (opt-in)

Stricter checks for code written by AI tools. Disabled by default.

aiAssistedReview: {
  enabled: true,
  gate: 'warn',
  strictScanMode: 'decorator',  // 'decorator' | 'pr-disclosure' | 'both'
}

Mark AI-generated code with inline comments:

// @frontguard-ai:start
const result = eval(userInput)  // flagged: eval in AI region
// @frontguard-ai:end

Detects: eval(), dangerouslySetInnerHTML, @ts-ignore, empty catch, new Function(), plain HTTP URLs, tokens in localStorage, dynamic SQL, and more.


Requirements

  • Node.js ≥ 18
  • Git (for diff and baseline operations)
  • Bitbucket Cloud pipelines (for PR context and comment posting)

License

MIT