Next.js and React audit CLI

One command.
Full picture of your app.

Finds the secret in your client bundle, the route shipping half a megabyte, and the payment handler that will charge twice.

>npx next-doc
Read the source
  • 4 plugins
  • 22 rules
  • 0 network calls
  • 2.3kb runtime
  • 7 frameworks

The report

Every finding carries a file, a line, and what to change.

npx next-doc
NEXT DOC
Next.js 15.1.0  TypeScript  App Router

ENV
   All 12 referenced variables are defined
   NEXT_PUBLIC_STRIPE_SECRET_KEY looks like a secret exposed to the client
      src/lib/stripe.ts:3
      Suggestion: Rename it without the NEXT_PUBLIC_ prefix, read it server side only.

SECURITY
   2 security headers are not configured: Permissions-Policy, HSTS
      next.config.mjs
   Client component ProfileForm.tsx pulls in server package "pg"
      src/lib/data.ts:1
      Suggestion: Move it to a Server Component, pass the result down as props.

PERFORMANCE
   StaticCard.tsx is a Client Component with no interactivity detected
   /dashboard ships 487kb of JavaScript, the largest route in the app

IDEMPOTENCY
   app/api/payments/route.ts has no idempotency key handling detected
      app/api/payments/route.ts:3
      Suggestion: Wrap it with withIdempotency from next-doc/idempotency.

Score: 61/100
4 errors, 3 warnings, 6 passed

Run next-doc --fix to apply 2 automatic fixes.
  • passed
  • warning, does not fail the build
  • error, exit code 1
  • plain ASCII outside a TTY

Four plugins

Run all of them, or name the ones you want.

env

Your code, your .env files and your template, checked against each other.

  • NEXT_PUBLIC_, VITE_, REACT_APP_ leaks
  • Read in code, defined nowhere
  • Drift from .env.example, fixable

security

The mistakes that pass code review and fail in production.

  • Server packages in client bundles
  • Unverified webhooks, open redirects
  • Missing headers and CSP

performance

Measured from your real build output, never estimated.

  • Routes over your JavaScript budget
  • "use client" with no interactivity
  • Fetches with no caching intent

idempotency

Money handling routes with no protection against a retry.

  • POST handlers on payment paths
  • Keys read but never stored
  • Ships a runtime fix, not just a finding

Runs in CI

Documented exit codes, versioned JSON, markdown for a pull request.

.github/workflows/audit.yml
# Bundle sizes need real build output.
- run: npm run build

- run: npx next-doc --json > next-doc-report.json
- run: npx next-doc --strict
Exit Meaning
0 Clean, or warnings without --strict
1 Errors found
2 Config invalid
3 Not a Next.js or React project
4 Internal error

withIdempotency

The scan finds the handler. This stops the double charge.

app/api/payments/route.ts
import { withIdempotency } from "next-doc/idempotency";
import { redisAdapter } from "next-doc/idempotency/redis";

export const POST = withIdempotency(
  async (request) => {
    const { amount } = await request.json();
    return Response.json(await charge(amount));
  },
  { adapter: redisAdapter({ client: redis }) },
);
Situation Response
Retry, same key Stored response, verbatim
Still in flight 409, never a queue
Key reused, new body 422
Storage down 503, fails closed
Handler threw Key released, retry works

Start in a minute

No config required. Works on Next.js, Vite, CRA, Remix, React Router, Astro.

  1. Run it

    >npx next-doc

    Detects the framework and runs what applies.

  2. Fix the safe things

    >npx next-doc --fix

    Writes .env.example only. It cannot touch .env or .env.production.

  3. Gate the branch

    >npx next-doc --strict

    Add next-doc.config.json when you want a rule turned off.