prompt-lint is a Node.js CLI that statically lints LLM prompts in your codebase. Think ESLint, but for prompts -- fast, rule-based, minimal dependencies, and built to run in CI.
Install from npm:
npm install prompt-lintRun without global install:
npx prompt-lintFor local development in this repository:
npm install
npm testLint the current directory:
npx prompt-lintLint a specific directory or file:
npx prompt-lint ./src
npx prompt-lint ./example/prompts.jsRun in CI mode (exit code 1 when issues are found):
npx prompt-lint --ci
npx prompt-lint --ci ./srcRun in strict mode (same failure behavior as CI mode):
npx prompt-lint --strict
npx prompt-lint --scan-rag --strictScan RAG documents for embedded injection attempts:
npx prompt-lint --scan-rag
npx prompt-lint --scan-rag ./docsMachine-readable output for CI/code scanning:
npx prompt-lint --format json
npx prompt-lint --format sarif
npx prompt-lint --scan-rag --format sarifDiff against a saved baseline:
npx prompt-lint --baseline .promptlint-baseline.jsonTrack trends across runs:
npx prompt-lint --trend-file .promptlint-trend.jsonGitHub PR annotations (workflow command output):
npx prompt-lint --github-annotations --format sarifprompt-lint reads configuration from .promptlintrc in the current project root (process.cwd()).
⚠ src/prompts/supportPrompt.ts
Line 14
Rule: vaguePrompt
Message: Prompt may be ambiguous.
Suggestion: Use a clear action verb and provide more context.
Scanned prompts: 12
Warnings: 3
3 prompt issues detected.
Exit codes:
0: success (--ci/--strictwith no issues, or standard lint mode)1:--cior--strictmode found one or more prompt issues2: runtime/configuration error
Output formats:
text(default): human-readable console outputjson: machine-readable warnings and summarysarif: SARIF 2.1.0 output for code-scanning integrations
Rich output flags:
--baseline <file>: compare current issues against a saved JSON baseline (warningsarray).--trend-file <file>: append run metrics and print the issue trend delta.--github-annotations: output GitHub Actions::warningannotations for each warning.
prompt-lint supports custom rule plugins using the package naming convention prompt-lint-plugin-*.
Add plugins in .promptlintrc:
{
"plugins": ["enterprise-style", "prompt-lint-plugin-internal-vocab"]
}Resolution behavior:
enterprise-styleresolves toprompt-lint-plugin-enterprise-stylefirst, thenenterprise-styleprompt-lint-plugin-internal-vocabresolves directly
Each plugin should export either:
rules: Rule[]rules: { [name]: Rule }Rule[]directly
Rule interface:
{
name: 'internalRuleName',
check(promptText, config) {
return null; // or { rule, message, suggestion? }
}
}openai.chat.completions.createclient.chat.completions.createanthropic.messages.createmodel.generateContentai.generateText
Extracted fields:
promptcontentmessages[].content
vaguePrompt: warns when a prompt is both short (<8 words) and missing a clear instruction verb.missingOutputFormat: warns when no output shape is specified (JSON, bullets, table, CSV, XML, markdown, etc).conflictingInstructions: warns on contradictory constraints (e.g. "short but comprehensive").tokenExplosion: warns when prompt length exceedsmaxPromptLengthfrom config (default1000).tokenUsage: warns when prompt length is above ~1500 chars. Uses a character-length heuristic for now.promptInjection: optional rule to flag jailbreak/injection-like instructions.ragPromptInjection: scans RAG knowledge documents for injection/jailbreak directives when--scan-ragis enabled. Covers patterns like "ignore previous instructions", "reveal the system prompt",[INST]tags, "pretend you are", and more.
Create a .promptlintrc file in your project root:
{
"maxPromptLength": 800,
"requireOutputFormat": true,
"enablePromptInjectionRule": true
}Supported options:
maxPromptLength(number): threshold fortokenExplosion. Default:1000.requireOutputFormat(boolean): whenfalse, disablesmissingOutputFormat. Default:true.enablePromptInjectionRule(boolean): whentrue, enablespromptInjection. Default:false.include(string[]): optional glob patterns to include files (applies to prompt and RAG scans).exclude(string[]): optional glob patterns to exclude files (applies to prompt and RAG scans).plugins(string[]): optional plugin package names (e.g.enterprise-style).
Example for a monorepo:
{
"include": ["packages/**/src/**/*.ts", "apps/**/src/**/*.tsx"],
"exclude": ["**/*.test.ts", "**/*.stories.tsx", "dist/**"]
}Create .promptlintignore in the project root to skip files/directories with glob patterns:
# generated outputs
dist/**
coverage/**
packages/**/generated/**
.promptlintignore is applied alongside include/exclude globs. Useful for monorepos.
Use --scan-rag to scan knowledge documents in addition to prompt strings.
Supported document file types:
.md.txt.json.csv
The scanner checks each line against the ragPromptInjection rule and flags suspicious instructions like:
ignore previous instructionsreveal the system promptsystem override[INST]/[system]tagspretend you are...
Example:
prompt-lint --scan-rag- Fast
- Minimal dependencies
- Clean, readable code
- Production-ready static checks