ESLint for your LLM prompts — catch prompt-injection risks, missing token limits, and prompt anti-patterns before you ship.
Project description
🧹 promptlint
ESLint for your LLM prompts.
You lint your code. Why not the prompts your code sends to the model?
promptlint is a tiny, zero-dependency linter that catches prompt-injection risks, missing token limits, hardcoded secrets, and prompt anti-patterns — before they ship.
⭐ If this catches even one bug for you, star the repo so others find it.
Why?
Prompts are code now — but nothing checks them. The same string gets shipped with user input glued straight into it (hello, prompt injection), no max_tokens (hello, surprise bill), and a hardcoded sk-... key two lines up. promptlint is the linter for exactly that.
$ promptlint app.py
app.py:6:1: PL003 error Hardcoded API key/secret — move it to an environment variable.
app.py:11:1: PL001 warning Untrusted input is interpolated into a prompt — delimit or validate it.
app.py:19:1: PL002 warning LLM call has no token limit (max_tokens) — set one to cap cost.
app.py:20:1: PL005 info Hardcoded model id — centralize it in config so models are easy to swap.
promptlint: 4 issue(s) in 1 file(s) — 1 error, 2 warning, 1 info
Install
pip install llm-promptlint
The PyPI package is
llm-promptlint(the namepromptlintwas taken); the command and import staypromptlint.
Or run straight from source (no dependencies, pure stdlib):
git clone https://github.com/pop123-ux/promptlint.git
cd promptlint && python -m promptlint path/to/your/code
Usage
promptlint . # lint the current project
promptlint app.py prompts/ # lint specific files/dirs
promptlint . --strict # fail on warnings too (great for CI)
promptlint . --select PL001,PL003 # only these rules
promptlint . --ignore PL005 # everything except this rule
promptlint --list-rules # show all rules
Exit code is 1 when any error is found (or any finding with --strict), so it drops straight into CI and git hooks.
Suppress a line
api_key = "sk-..." # promptlint: disable=PL003
prompt = f"..." # promptlint: disable (silences all rules on this line)
The rules
| Code | Severity | Catches |
|---|---|---|
| PL001 | warning | Untrusted input (user_input, request.*, argv, …) interpolated/concatenated into a prompt — prompt-injection risk. |
| PL002 | warning | LLM completion call with no max_tokens — uncapped cost and output. |
| PL003 | error | Hardcoded API key/secret (sk-, sk-ant-, AIza…, ghp_…, …). |
| PL004 | warning | Long prompt with no output-format instruction (no JSON/schema/structure). |
| PL005 | info | Hardcoded model id (gpt-…, claude-…, gemini-…) instead of config. |
| PL006 | info | messages[] with a user role but no system role. |
High-signal by design — it flags the mistakes that actually ship, not stylistic noise. Works on Python, JS/TS, and any text/prompt files.
Use as a pre-commit hook
Add to your .pre-commit-config.yaml:
repos:
- repo: https://github.com/pop123-ux/promptlint
rev: v0.1.0
hooks:
- id: promptlint
Now every commit is scanned, and insecure prompts never make it in.
Use in CI (GitHub Actions)
- uses: actions/setup-python@v5
with: { python-version: "3.x" }
- run: pip install llm-promptlint
- run: promptlint . --strict
Roadmap
- Config via
pyproject.toml([tool.promptlint]) - More rules: temperature sanity, retry/backoff, PII in prompts, system-prompt leakage
- JSON output (
--format json) for dashboards - Per-rule auto-fix suggestions
PRs welcome — see CONTRIBUTING. New rule ideas are especially appreciated.
License
Built by @pop123-ux · Lint your prompts. Ship with confidence. ⭐
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llm_promptlint-0.1.0.tar.gz.
File metadata
- Download URL: llm_promptlint-0.1.0.tar.gz
- Upload date:
- Size: 9.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
228837e2f5ed008f070b5b444fdfa953099adbf650fa7448a10d86adc40f00b3
|
|
| MD5 |
98a41d5acb1bbf8f83b5b2dd41a304f9
|
|
| BLAKE2b-256 |
71790aa5c9921fd2f49632937103883e049d473ac6d1116ba70bb0233b5c7f38
|
File details
Details for the file llm_promptlint-0.1.0-py3-none-any.whl.
File metadata
- Download URL: llm_promptlint-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ab888a5c5dccfa123b8aa19442fb213f13b860ffe4ab21e28fc1dd0d51a1270
|
|
| MD5 |
6752186de9416e2352d48dcc3d8362a6
|
|
| BLAKE2b-256 |
036fdfe55165998d1173d45da13e1f385ffd7008f99015975d17ba6737fa2749
|