Repository navigation
Releases: simonvanlierde/jsonvet
Release list
jsonvet 3.0.0
3.0 checks files against a JSON Schema and puts each error at its line and column, in every dialect, comments and JSON5 included. It also writes SARIF for GitHub code scanning, and it ships as a GitHub Action.
Upgrade
Set rev: v3.0.0 in .pre-commit-config.yaml, or uses: simonvanlierde/jsonvet@v3. Most hook users need nothing else. Check the breaking changes below if you run jsonvet from a directory other than its config file's, pass it unknown options from a script, match its paths in a script, or use the Rust library.
What's new
--schema FILE: checks each file against one JSON Schema, offline. Errors come under the ruleschema, at the line and column of the value, with its JSONPath:server.json5:3:9: error[schema] "80" is not of type "integer" (at $.port). It is in every build, the hook and the Action included.--format sarif: one SARIF 2.1.0 document for GitHub code scanning, with the same exit codes as text.- A GitHub Action:
uses: simonvanlierde/jsonvet@v3checks the repository's tracked JSON files, or thefilesyou give it, on Linux, macOS and Windows runners. Withsarif:it also writes a SARIF file for code scanning. - Safer output: file names and messages escape control, bidi and invisible characters, so a file name cannot forge a GitHub annotation or reorder a terminal line.
- A DOI: each release from this one on gets a Zenodo DOI, and
CITATION.cffsays how to cite jsonvet.
Breaking changes
dialectspatterns injsonvet.tomlor[tool.jsonvet]match paths relative to that file, not to the working directory.- An unknown option such as
--xor-xexits 2 instead of 1, unless a file of that name exists. - Non-ASCII keys in paths print as written,
$["日本"]and not$["\u65e5\u672c"]. - Rust library:
Rule::ALLandDialect::ALLare slices,SeverityandLocationare#[non_exhaustive], andUnknownRuleandUnknownDialecthide their text behindid()andname().
The full list, with the fixes, is in the changelog.
Install
uvx jsonvet, pip install jsonvet or cargo install jsonvet-cli. The Rust library is the jsonvet crate.
v2.0.0: check-json5 is now jsonvet, rewritten in Rust
check-json5 is now jsonvet, rewritten in Rust. It gives the same pass or fail as 1.4.1 on every file: I ran both on 20,114 files in JSON5 and strict mode, 40,228 runs, and they agree on all of them.
Upgrade
Set rev: v2.0.0 in .pre-commit-config.yaml. The check-json5 hook id, the check-json5 command and --strict keep working until 3.0, and the old repository URL redirects. To use the new options, switch to the jsonvet hook id.
What's new
- Six dialects on one parser: JSON, I-JSON, JSONC, JWCC (HuJSON), JSON5 and JSON Lines, picked by file extension or with
--dialect. - Rules with severities:
duplicate-key,invalid-number,byte-order-markand more, changed with--error,--warn,--ignoreand--max-warnings. - A config file:
jsonvet.toml, or[tool.jsonvet]inpyproject.toml. - Faster, with no Python start-up: the hook installs a prebuilt binary. It is 3x faster on 1,100 small config files and 1,398x faster on a 1.8 MB JSON5 file.
Breaking changes
- Each output line gains its severity and rule, as in
file:4:5: error[duplicate-key] duplicate key $.a (first at 2:5), and syntax errors use new wording. - Lines end at every JSON5 line terminator, so positions after a lone CR, U+2028 or U+2029 differ from 1.x.
- The importable Python module is gone. The wheel brings the
jsonvetandcheck-json5commands.
The full list is in the changelog.
Install
uvx jsonvet, pip install jsonvet or cargo install jsonvet-cli. The Rust library is the jsonvet crate.
v1.4.1
Upgrade: set rev: v1.4.1. Nothing else is needed.
Fixed
--strictpassed a file whereNaNorInfinityruns on into other text, such as[NaN-2.5e3orInfinitynul }. Those files now fail, with the constant's position.- An unquoted JSON5 key written with a
\uescape, such asa, was compared with its escape still in place, so it did not matchaor'a', and its path showed the escape. Keys now compare by their decoded name.
v1.4.0
Upgrade: set rev: v1.4.0. Nothing else is needed.
Added
- The hook also runs on Tailscale's
.hujsonand.jwcc, VS Code's.code-workspaceand
.code-snippets,.webmanifestand.babelrcfiles: all JSON, some with comments.
Changed
- The hook checks JSON with only comments and trailing commas, such as
tsconfig.json, with the
C-speedjsonparser instead ofjson5. Whole hook runs are 11× faster on a 50 KB file and
56× faster on a 2 MB one. Files that use more of JSON5 still go throughjson5. - A number may have up to 1,000,000 digits. 1.3.0 lifted Python's limit of 4300 altogether,
which let one file with a huge number stall a run. A longer number now fails its file with a
message.
Fixed
- A JSON5 file with comments and an unescaped U+2028 or U+2029 inside a string now passes, as
the JSON5 spec allows. Thejson5package rejected it; strict JSON files already passed. - A file with a duplicate key and an undecodable string after it crashed the run with a
traceback and left the remaining files unchecked. It now reports the duplicate. - A newline in a file name is printed as
\n, so a file name can no longer inject a GitHub
Actions workflow command into CI output. - Checking a file with many duplicate keys took time that grew with the square of their
number. 200,000 duplicates took 42 s; they now take under a second. --strictpatterns match./sub/a.jsonlikesub/a.json.
v1.3.0
Upgrade: set rev: v1.3.0. Nothing else is needed for the hook. Only a script that parses the
hook's output, or imports pre_commit_hooks.check_json5, needs a change (see Changed).
Added
- Every failure prints as
file:line:col: message, so editors and terminals link to it. - A duplicate key reports its JSON path (
$.server.port), and every repeated key in a file is
listed, not only the first. - On GitHub Actions, each failure is also an annotation on the pull request diff.
--strict GLOBholds matching files to strict JSON: no comments, trailing commas orNaN.
Repeat it to add patterns, and!GLOBexempts files.- Published on PyPI, so
uvx check-json5 FILE...works without pre-commit.
Changed
- The output format:
f.json: Failed to json decode (<string>:4 Unexpected "," at column 8)is
nowf.json:4:8: Unexpected ",". - The module moved from
pre_commit_hooks.check_json5tocheck_json5.check_json5, so the PyPI
package no longer collides withpre-commit-hooks. Thecheck-json5command is unchanged. - Tested on Python 3.15.
Fixed
- A file nested deeper than Python's recursion limit crashed the run and left the remaining files
unchecked. It now fails on its own. - Valid JSON with an integer of more than 4300 digits failed.
v1.2.0
Highlights
- Faster validation: new fast
jsonparse path, falling back to json5/jsonc only when needed. .jsonc/.json5support: the hook now covers comment-bearing JSON variants (plus.geojson/.jsonld).
Also in this release
- Add CI workflow
- Add test suite
- Update dependencies, ruff config, and uv lockfile
- README: performance notes and badges
Full Changelog: v1.1.0...v1.2.0