cd /news/ai-tools/show-hn-jev-lint-semantic-linter-wit… · home topics ai-tools article
[ARTICLE · art-134839] src=github.com ↗ pub= topic=ai-tools verified=true sentiment=· neutral

Show HN: Jev-lint – semantic linter with plain English rules

Developer zdenham released jev-lint, an open-source semantic linter that checks JavaScript and TypeScript code against project conventions written in plain English, using Jev models through Vercel AI Gateway. The tool requires Node.js 22.22+ and Git, defaults to a 20-finding and 16 KiB output limit, and is an early release whose findings should be reviewed before being made to block CI. Rules are defined in jev.config.json or referenced from Markdown files, and live checks consume the user's Vercel AI Gateway credits via an AI_GATEWAY_API_KEY.

read4 min views2 publishedSep 19, 2026
Show HN: Jev-lint – semantic linter with plain English rules
Image: Michielbdejong (auto-discovered)

Check JavaScript and TypeScript code against project conventions written in plain English. Write a rule or point to a Markdown file with examples; Jev evaluates the relevant code and reports possible violations.

Built for coding agents, with compact output by default and optional pretty or JSON output. Early release; review findings before making them block CI.

Define your conventions in jev.config.json. Each rule has a name and a plain-English instruction, with optional file patterns:

{
  "files": ["src/**/*.{ts,tsx}"],
  "ignore": ["src/generated/**"],
  "rules": {
    "preserve-error-cause": {
      "instruction": "When rethrowing an unexpected error, preserve the original error as its cause.",
      "severity": "error"
    },
    "user-facing-errors": {
      "files": ["src/ui/**"],
      "instruction": { "file": "docs/conventions.md#user-facing-errors" }
    }
  }
}

Paths are relative to the config file. Rule-specific patterns narrow the top-level files selection. Severity defaults to warning; use error to fail the check.

For Markdown rules, include the convention, examples, and exceptions:

## User-facing errors

Explain what went wrong and what the user can do next.

Good: "We couldn't save your changes. Check your connection and try again."
Bad: "Mutation failed: ERR_UPSTREAM_502."

This applies to messages shown to users, not internal logs.

A #heading reference includes its subsections and code examples. Omit the fragment to use the whole file as one rule. Markdown files must be inside the config directory or its descendants. Examples guide the judgment; they are never executed.

Requires Node.js 22.22+ and Git. Clone the repo, build it, and register the global command:

git clone https://github.com/zdenham/jev-lint.git
cd jev-lint
npm ci
npm run build
npm link
jev-lint --help

You can now run jev-lint from any project directory. Keep this checkout in place: the global command links to it. If your shell cannot find the command, ensure npm's global executable directory is on your PATH ($(npm prefix --global)/bin on macOS/Linux).

To update, run git pull, npm ci, and npm run build inside the checkout. To remove the global command, run npm uninstall --global jev-lint.

cd /path/to/your-project
jev-lint init

This creates jev.config.json without installing anything in your project. Edit its rules, then run jev-lint --dry-run to preview the scope and jev-lint to check it.

For live checks, get a Vercel AI Gateway API key. Set it in the environment, or put it in .env.local beside jev.config.json:

export AI_GATEWAY_API_KEY="your-key"

Selected source code and rules are sent to Jev through Vercel AI Gateway, using your account's credits. No Vercel deployment is needed. Add these to your project's .gitignore:

.env.local
.jev/reports/
jev-lint --dry-run          # Preview files and rules; no API calls
jev-lint                   # Check configured files
jev-lint src/ui            # Narrow to a file or directory
jev-lint --changed main    # Check whole tracked files changed from main's merge-base
jev-lint --format pretty   # Human-readable code frames
jev-lint --format json     # Programmatic output

Agent output includes file locations, rule references, usage, and a saved report. Large results are truncated explicitly; defaults are 20 findings and 16 KiB of output.

[f_1] ERROR preserve-error-cause
src/save.ts:1:1
  Possible violation of preserve-error-cause; compare the code with the rule and its examples.
  ...
Rule: jev.config.json#/rules/preserve-error-cause/instruction
Report: /your-project/.jev/reports/<run-id>.json

Inspect a saved report without another API call:

jev-lint report /path/to/report.json --finding f_1
jev-lint report /path/to/report.json --offset 20 --limit 20

Use --summary for counts only, or --max-output-bytes to set the output budget. Run jev-lint --help for all options.

Every run prints input/output token counts and Gateway's billed and market costs. Illustrative output:

Usage: 3 requests | 5000 input tokens | 500 output tokens
Cost: $0.00021000 billed | $0.00021000 market

At $0.042 per million input tokens, 5,000 input tokens cost $0.00021. These are example numbers, not a benchmark. Actual cost depends on source size, rules, and current pricing. Missing usage or cost data is marked as incomplete or unavailable.

The default run budget is $1, with caps of 10 files, 10 requests, and 100,000 total input bytes. Set these in the top-level limits object of jev.config.json:

"limits": {
  "maxCostUsd": 1,
  "maxFiles": 10,
  "maxRequests": 10,
  "maxInputBytes": 100000
}

Omitted limits use the defaults. Override individual limits for one run:

jev-lint --dry-run                 # Offline estimate; no API calls
jev-lint --max-cost-usd 0.25        # Override the config's dollar budget
jev-lint --max-files 30 --max-requests 30

Live runs check current Gateway pricing before evaluation. An over-budget estimate prevents evaluation; reported costs are checked between requests, using market value even when credits reduce the bill. Dry-run estimates use a dated local pricing snapshot.

The dollar budget is a client-side guardrail, not a guaranteed billing cap: an in-flight request can cost more than estimated. Budget stops exit 2 and save partial results. A zero dollar budget blocks evaluation. Each selected file uses at most one evaluation request; fresh runs are not cached.

Findings identify top-level declarations or class members. The initial version uses the selected file as context and does not resolve imports. Uncertain checks are counted separately, not treated as proof of compliance. The tool does not edit code.

Exit codes: 0 within finding limits, 1 error findings or excess warnings, 2 configuration or execution failure. To make warnings fail CI:

jev-lint --max-warnings 0
npm run check   # Type checking, offline tests, and build
jev-lint --config examples/jev.config.json

Export AI_GATEWAY_API_KEY before running the example (or put it in examples/.env.local). The example intentionally reports one violation and exits 1. Source modules stay under 250 lines. Implementation notes and evaluation guidance live in plan/.

── more in #ai-tools 4 stories · sorted by recency
── more on @jev-lint 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-jev-lint-sem…] indexed:0 read:4min 2026-09-19 ·