prodlint
Static analysis for vibe-coded apps. Flags security, reliability, performance, and AI quality issues in code generated by Cursor, v0, Bolt, and Copilot.
README
prodlint
Production readiness for vibe-coded apps.
Static analysis for vibe-coded apps. Flags the security, reliability, performance, and AI quality issues that Cursor, v0, Bolt, and Copilot create — hallucinated imports, missing auth, hardcoded secrets, unvalidated server actions, and more. Zero config, no LLM, 52 rules.
npx prodlint
prodlint v0.9.5
Scanned 148 files · 2 critical · 5 warnings · 1 info
src/app/api/checkout/route.ts
12:1 INFO No rate limiting — anyone could spam this endpoint and run up your API costs rate-limiting
28:5 WARN Empty catch block silently swallows error shallow-catch
src/actions/submit.ts
5:3 CRIT Server action uses formData without validation next-server-action-validation
↳ Validate with Zod: const data = schema.safeParse(Object.fromEntries(formData))
src/lib/db.ts
1:1 CRIT Package "drizzle-orm" is imported but not in package.json hallucinated-imports
Scores
security 72 ████████████████░░░░ (8 issues)
reliability 85 █████████████████░░░ (4 issues)
performance 95 ███████████████████░ (1 issue)
ai-quality 90 ██████████████████░░ (3 issues)
Overall: 82/100 (weighted)
2 critical · 5 warnings · 4 info
Why?
Vibe coding is the fastest way to build. Shipping fast means knowing your code is production-ready — not just that it compiles. Hardcoded secrets, hallucinated packages, missing auth, and XSS vectors pass type-checks and look correct — but they aren't ready for production.
prodlint checks what TypeScript and ESLint don't: whether your vibe-coded app is ready for production.
Install
npx prodlint # Run directly (no install)
npx prodlint ./my-app # Scan specific path
npx prodlint --json # JSON output for CI
npx prodlint --sarif # SARIF 2.1.0 for GitHub Code Scanning
npx prodlint --summary # Quick pass/fail + top 3 blockers
npx prodlint --profile startup # Only critical findings
npx prodlint --profile strict # All findings including info
npx prodlint --baseline .prodlint-baseline.json # Only new findings
npx prodlint --ignore "*.test.ts" # Ignore patterns
npx prodlint --min-severity warning # Only warnings and criticals
npx prodlint --quiet # Suppress badge output
Or install it:
npm i -D prodlint # Project dependency
npm i -g prodlint # Global install
52 Rules across 4 Categories
Security (27 rules)
| Rule | What it checks |
|---|---|
secrets |
API keys, tokens, passwords hardcoded in source |
auth-checks |
API routes with no authentication |
env-exposure |
NEXT_PUBLIC_ on server-only secrets |
input-validation |
Request body used without validation |
cors-config |
Access-Control-Allow-Origin: *, wildcard + credentials escalated to critical |
unsafe-html |
dangerouslySetInnerHTML with user data |
sql-injection |
String-interpolated SQL queries (ORM-aware) |
open-redirect |
User input passed to redirect() |
rate-limiting |
API routes with no rate limiter |
phantom-dependency |
Packages in node_modules but missing from package.json |
insecure-cookie |
Session cookies missing httpOnly/secure/sameSite |
leaked-env-in-logs |
process.env.* inside console.log calls |
insecure-random |
Math.random() used for tokens, secrets, or session IDs |
next-server-action-validation |
Server actions using formData without Zod/schema validation |
env-fallback-secret |
Security-sensitive env vars with hardcoded fallback values |
verbose-error-response |
Error stack traces or messages leaked in API responses |
missing-webhook-verification |
Webhook routes without signature verification |
server-action-auth |
Server actions with mutations but no auth check |
eval-injection |
eval(), new Function(), dynamic code execution |
next-public-sensitive |
NEXT_PUBLIC_ prefix on secret env vars |
ssrf-risk |
User-controlled URLs passed to fetch in server code |
path-traversal |
File system operations with unsanitized user input |
unsafe-file-upload |
File upload handlers without type or size validation |
supabase-missing-rls |
CREATE TABLE in migrations without enabling RLS |
deprecated-oauth-flow |
OAuth Implicit Grant (response_type=token) |
jwt-no-expiry |
JWT tokens signed without an expiration |
client-side-auth-only |
Password comparisons or auth logic in client components |
Reliability (11 rules)
| Rule | What it checks |
|---|---|
hallucinated-imports |
Imports of packages not in package.json |
error-handling |
Async operations without try/catch |
unhandled-promise |
Floating promises with no await or .catch |
shallow-catch |
Empty catch blocks that swallow errors |
missing-loading-state |
Client components that fetch without a loading state |
missing-error-boundary |
Route layouts without a matching error.tsx |
missing-transaction |
Multiple Prisma writes without $transaction |
redirect-in-try-catch |
redirect() inside try/catch — Next.js redirect throws, catch swallows it |
missing-revalidation |
Server actions with DB mutations but no revalidatePath |
missing-useeffect-cleanup |
useEffect with subscriptions/timers but no cleanup return |
hydration-mismatch |
window/Date.now()/Math.random() in server component render path |
Performance (6 rules)
| Rule | What it checks |
|---|---|
no-sync-fs |
readFileSync in API routes |
no-n-plus-one |
Database calls inside loops |
no-unbounded-query |
.findMany() / .select('*') with no limit |
no-dynamic-import-loop |
import() inside loops |
server-component-fetch-self |
Server components fetching their own API routes |
missing-abort-controller |
Fetch/axios calls without timeout or AbortController |
AI Quality (8 rules)
| Rule | What it checks |
|---|---|
ai-smells |
any types, console.log, TODO comments piling up |
placeholder-content |
Lorem ipsum, example emails, "your-api-key-here" left in production code |
hallucinated-api |
.flatten(), .contains(), .substr() — methods AI invents |
stale-fallback |
localhost:3000 hardcoded in production code |
comprehension-debt |
Functions over 80 lines, deep nesting, too many parameters |
codebase-consistency |
Mixed naming conventions across the project |
dead-exports |
Exported functions that nothing imports |
use-client-overuse |
"use client" on files that don't use any client-side APIs |
Smart Detection
prodlint avoids common false positives:
- AST parsing — Babel-based analysis for 12 rules (imports, catch blocks, redirects, SSRF, path traversal, JWT, HTML injection, hydration, transactions, env leaks, loops, SQL) with regex fallback
- Monorepo support — npm/yarn/pnpm workspace dependencies resolved automatically
- Framework awareness — Prisma, Drizzle, Supabase, Knex, and Sequelize whitelists prevent false SQL injection flags
- Middleware detection — Clerk, NextAuth, Supabase middleware detected — auth findings downgraded
- Block comment awareness — patterns inside
/* */are ignored - Path alias support —
@/,~/, and tsconfig paths aren't flagged as hallucinated imports - Route exemptions — auth, webhook, health, and cron routes are exempt from auth/rate-limit checks
- Test/script file awareness — lower severity for non-production files
- Fix suggestions — findings include actionable
fixhints with remediation code
Scoring
Each category starts at 100. Deductions per finding:
| Severity | Deduction | Per-rule cap |
|---|---|---|
| critical | -8 | max 1 |
| warning | -2 | max 2 |
| info | -0.5 | max 3 |
Diminishing returns: after 30 points deducted in a category, further deductions are halved; after 50, quartered.
Weighted overall: security 40%, reliability 30%, performance 15%, ai-quality 15%. Floor at 0. Exit code 1 if any critical findings exist.
GitHub Action
Add to .github/workflows/prodlint.yml:
name: Prodlint
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: prodlint/prodlint@v1
with:
threshold: 50
Posts a score breakdown as a PR comment and fails the build if below threshold.
| Input | Default | Description |
|---|---|---|
path |
. |
Path to scan |
threshold |
0 |
Minimum score to pass (0-100) |
ignore |
Comma-separated glob patterns to ignore | |
comment |
true |
Post PR comment with results |
| Output | Description |
|---|---|
score |
Overall score (0-100) |
critical |
Number of critical findings |
SARIF + GitHub Code Scanning
Upload prodlint results to GitHub's Security tab:
- name: Run prodlint
run: npx prodlint --sarif > prodlint.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: prodlint.sarif
category: prodlint
Baseline for Existing Projects
Adopt prodlint gradually without drowning in pre-existing findings:
# Save current state as baseline
npx prodlint --baseline-save .prodlint-baseline.json
# CI only fails on NEW findings
npx prodlint --baseline .prodlint-baseline.json
MCP Server
Use prodlint inside Cursor, Claude Code, or any MCP-compatible editor:
Claude Code:
claude mcp add prodlint -- npx -y prodlint-mcp
Cursor / Windsurf:
{
"mcpServers": {
"prodlint": {
"command": "npx",
"args": ["-y", "prodlint-mcp"]
}
}
}
Ask your AI: "Run prodlint on this project" and it calls the scan tool directly.
Site Score
Check any deployed website for AI agent-readiness — 14 checks covering emerging standards like llms.txt, TDMRep, AgentCard, AI-Disclosure, HTTP Signatures (RFC 9421), and more.
npx prodlint --web example.com
npx prodlint --web example.com --json # JSON output
prodlint site score
example.com · 14 checks
Score: 42 C ████████░░░░░░░░░░░░
✗ AI-Disclosure Header 0/10 No AI-Disclosure header found.
✗ Content-Usage Directives 0/10 No Content-Usage directives found.
✗ TDMRep 0/10 No TDMRep found.
✗ A2A AgentCard 0/5 No agent-card.json found.
✗ ai.txt 0/5 No ai.txt found at site root.
! llms.txt 2/5 llms.txt found but missing key sections.
✓ robots.txt 10/10 robots.txt found with 15 rules.
✓ Sitemap 10/10 Valid sitemap with 42 URLs.
✓ Structured Data 10/10 Found JSON-LD structured data.
✓ OpenGraph 10/10 Complete OpenGraph tags found.
✓ Page Speed 5/5 Loaded in 0.8s.
✓ AI Bot Directives 5/5 AI-specific bot rules found.
✓ WebMCP Tools 0/5 No WebMCP tools detected.
7 passed · 5 failed · 1 warnings
Full results: https://prodlint.com/score?url=example.com
Or check your score interactively at prodlint.com/score.
For AI Tools
- LLM-friendly docs: prodlint.com/llms.txt — concise project summary for LLMs
- Full reference: prodlint.com/llms-full.txt — all 52 rules with details
- MCP setup guide: prodlint.com/mcp — detailed editor setup for Claude Code, Cursor, Windsurf
prodlint is designed specifically for AI-generated code patterns. Every rule checks for production issues that AI coding tools consistently create — not style nits.
Suppression
Suppress a single line:
// prodlint-disable-next-line secrets
const key = "sk_test_example_for_docs"
Suppress an entire file (place at top):
// prodlint-disable secrets
Programmatic API
import { scan } from 'prodlint'
const result = await scan({ path: './my-project' })
console.log(result.overallScore) // 0-100
console.log(result.findings) // Finding[]
Badge
[](https://prodlint.com)
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。