[Free check]

Check your Next.js app
in one command.

24 checks for the problems that pass lint, types and the build: open AI endpoints, retired models, unsigned webhooks, missing row level security and leaked keys. Runs locally in about a second. No install, no account.

$ npx whirlwindai

Source on GitHub·npm·MIT licence

~/acme-notes · npx whirlwindai --quiet
whirlwindai check · acme-notes
Next.js 15.2 (App Router) · Supabase · Stripe · OpenAI, Anthropic
 
AI cost
✗ Every endpoint that calls a model checks who is calling ai-auth
✗ app/api/summarize/route.ts calls a model (OpenAI) with no sign-in check
Anyone on the internet can call it and spend your AI budget.
✗ No retired or deprecated model IDs models
✗ lib/ai.ts uses claude-3-5-sonnet-20241022, which the provider has retired
 
Auth
✗ No open redirects open-redirect
✗ app/auth/callback/route.ts redirects to the "next" query parameter unchecked
 
Database
! Privileged database functions are locked down supabase-rpc
! supabase/migrations/001_init.sql add_credits() is SECURITY DEFINER and callable by anyone
Supabase exposes it at /rest/v1/rpc/add_credits.
 
3 problem(s), 1 warning(s) · 24 checks · 0.1s

What it checks

The mistakes AI agents make most

Secrets

  • .env files committed to gitsecrets-tracked
  • OpenAI, Anthropic, Stripe, Google, Resend and GitHub keys in the codesecrets-hardcoded
  • Secrets in NEXT_PUBLIC_ variables, which ship to every visitorsecrets-public

AI cost

  • API routes and server actions that call a model without checking who is callingai-auth
  • Model calls with no rate limit, credits or quotaai-limit
  • Model IDs the provider has retired or deprecatedmodels

Payments

  • Stripe webhooks that skip the signature checkstripe-webhook
  • Checkout amounts or price IDs taken from the requeststripe-price
  • Success and cancel URLs built from the caller's Origin headerstripe-redirect
  • Lemon Squeezy, Paddle, Polar, Clerk and GitHub webhooks that don't verify the senderwebhooks

Auth

  • ?next= and similar parameters redirected to without a checkopen-redirect
  • Links built from the caller's Origin or Host header, especially emailed onesorigin-links
  • Server code trusting auth.getSession()supabase-session

Database

  • Tables without row level security, and policies that allow any writesupabase-rls
  • SECURITY DEFINER functions anyone can call through the APIsupabase-rpc
  • Tables the code queries that no migration createssupabase-tables
  • Firebase rules that allow everyone, including expired test-mode rulesfirebase-rules
  • SQL built by pasting values into the query textraw-sql

Code

  • Local and @/ imports that point at nothingimports
  • a + "text" || fallback, where the fallback can never runprecedence
  • Dynamic pages that return a 500 instead of a 404 for an unknown IDnot-found
  • Missing error and not-found pageserror-pages
  • next.config letting /_next/image fetch from any hostimage-proxy
  • Environment variables the code reads that .env.example doesn't listenv-example

Checks for a service only run when your project uses it. AI: OpenAI, Anthropic, Gemini, Vercel AI SDK, LangChain, LlamaIndex, Mastra, Bedrock, Groq, Mistral, Replicate and more. Auth: Supabase, Auth.js, Clerk, Kinde, Better Auth, Lucia, iron-session, tRPC, next-safe-action. Data: Supabase, Firebase, Prisma, Drizzle, pg. Payments: Stripe, Lemon Squeezy, Paddle, Polar.

How it works

Reads your code. Sends nothing.

The check reads your project on your machine, in a git repo following your .gitignore. It works with the App Router and the Pages Router, JavaScript and TypeScript, import aliases from your tsconfig, and monorepos (run it on each app, for example npx whirlwindai apps/web). Build scripts, tests, generated code and examples are skipped.

Add --deep to ask OpenAI, Anthropic and Google which models your keys can actually use. Each key is sent only to its own provider.

It reads code rather than running it, so it can miss a problem written in an unusual way, or flag something that is fine. Silence a finding with a comment that names the check and the reason: // whirlwind-check-ignore: ai-auth internal tool. Every check was tuned against real open-source apps, including Vercel's AI chatbot, Commerce and SaaS starter, Dub and chatbot-ui.

In CI

Check every pull request

The check exits 1 on problems and 2 on warnings only, so one line in a workflow stops a change that opens an AI route or skips a webhook signature from merging.

# .github/workflows/check.yml
name: check
on: [pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npx whirlwindai   # fails the build on problems

Coming next: Watch

Know before a model is retired

Some problems arrive without a code change. Providers retire models, deprecate APIs and change limits, and the first sign is usually an error in front of a user. The free check sees your code as it is when you run it.

Watch runs those checks for you:

  • ·A nightly live check of every model, service and key your app uses, with an email or Slack alert when one is deprecated or stops working
  • ·Findings posted on your pull requests, with a history across pushes
  • ·One view across all your repos, with shared ignore rules for teams

It isn't built yet. Join the waitlist and you'll hear first, with early pricing.

The free check and Whirlwind

Find the problems, or start without them

The free check is the general version of the Whirlwind audit, for an app you already have. Whirlwind is the Next.js AI SaaS starter where these problems are fixed from the start, with checks built for its own architecture that your agent runs after every change.

Free checkWhirlwind
24 general checks, on any Next.js app✓✓
Those problems fixed in the code from day one·✓
33 audit checks written for the template's architecture·✓
Live doctor: every service, migration and AI modelModels only, with --deep✓
27 end-to-end tests: signup, checkout, credits·✓
Contract files, so your agent avoids the mistakes in the first place·✓
PriceFree, open sourceOne payment