Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
JSON Linting in Continuous Integration Pipelines
A useful JSON linting step in CI does more than answer "is this file parseable?" It should reject malformed JSON, enforce a consistent format, and validate important files against a schema when syntax alone is not enough. That combination catches the failures that actually break deployments: invalid config files, drift in committed JSON, and structurally wrong data that still happens to parse.
The mistake many teams make is treating all of those checks as the same thing. They are not. A formatter like Prettier is great for consistency, but it will not replace schema validation. A parser check catches broken commas and quotes, but it will not tell you whether a feature-flag file is missing a required field. The most reliable CI pipeline keeps those checks separate so failures are easy to understand and fast to fix.
What JSON Linting In CI Should Cover
1. Parse Validity
Fail the job if a file is not strict JSON. This catches missing commas, invalid quotes, trailing commas, bad escape sequences, and comments in files that are supposed to be plain JSON.
Good for every repository that commits JSON.
2. Formatting
Keep indentation, whitespace, and line wrapping predictable. That makes diffs smaller and avoids noisy pull requests where machine-generated JSON gets reformatted differently on each branch.
Best when your team already standardizes on Prettier or another formatter.
3. Schema Validation
Validate the shape of critical JSON such as app config, deployment manifests, fixtures, feature flags, or contract-test payloads. This is the check that catches "valid JSON, wrong data".
Add this where bad structure would cause a release, runtime, or migration failure.
For most teams, the minimum reliable setup is parse checks plus formatting checks on every pull request, then schema validation for a short list of important files. That gives good coverage without turning the pipeline into a slow all-or-nothing gate.
Tool Choices That Hold Up In CI
`jq empty` or `jsonlint` for syntax
If all you need is a strict parser check, `jq empty file.json` is easy to script and exits non-zero on invalid input. If your team already uses `jsonlint`, that is fine too. The important part is that the CI step fails immediately on malformed JSON.
Prettier for formatting drift
Prettier's CLI `--check` mode is a good CI fit because it returns a failing exit code when files are not formatted, without rewriting them in the pipeline. Quote the glob pattern in shell commands so Prettier expands it instead of your shell.
Ajv CLI for JSON Schema
If you keep schemas in the repo, Ajv CLI is a practical choice for CI. It supports modern JSON Schema drafts and makes it clear which file failed and why. Use schema validation for files whose structure matters, not for every incidental JSON file in the repo.
GitHub Actions Example
GitHub stores workflow files in `.github/workflows`, and the workflow syntax supports `paths` filters. That makes JSON checks cheap enough to run on every pull request without rerunning them for unrelated changes.
name: JSON checks
on:
pull_request:
paths:
- "**/*.json"
- "schemas/**/*.json"
- ".github/workflows/json-checks.yml"
push:
branches:
- main
paths:
- "**/*.json"
- "schemas/**/*.json"
jobs:
json:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
- name: Install repo dependencies
run: npm ci
- name: Parse strict JSON files
run: |
find . \
-path './node_modules' -prune -o \
-path './.next' -prune -o \
-name '*.json' -exec jq empty {} +
- name: Check formatting
run: npx prettier --check "**/*.json"
- name: Validate critical config against schema
run: npx ajv validate --spec=draft2020 --all-errors -s schemas/app-config.schema.json -d config/app-config.jsonReplace `npm ci` with your project's package-manager install command. If you do not keep schemas in the repository, drop the Ajv step instead of forcing schema validation onto files that do not need it.
GitLab CI Example
GitLab pipelines start from a repository-root `.gitlab-ci.yml` file. A single JSON job is usually enough: install the parser and project dependencies, run a strict parse check, then run formatting and schema validation in sequence.
stages:
- lint
json_lint:
stage: lint
image: node:22
before_script:
- apt-get update
- apt-get install -y jq
- npm ci
script:
- find . -path './node_modules' -prune -o -name '*.json' -exec jq empty {} +
- npx prettier --check "**/*.json"
- npx ajv validate --spec=draft2020 --all-errors -s schemas/app-config.schema.json -d config/app-config.jsonCommon Failure Modes In Real Pipelines
- Linting JSONC or JSON5 as strict JSON: files like `tsconfig.json` may allow comments or trailing commas even though plain JSON does not. Exclude them or use tooling that matches the real file format.
- Checking too many files: generated snapshots, lockfiles, vendored JSON, and build output often create noise. Scope the job to the directories that matter.
- Using formatting as a proxy for validation: a formatter can tell you a file needs cleanup, but it cannot tell you whether a config object is missing `environment`, `version`, or another required field.
- Only validating on deploy: JSON checks belong on pull requests and branch pushes, not just release pipelines. Waiting until deploy makes the feedback loop too expensive.
- Ignoring duplicate-key risk: many parsers accept duplicate keys and keep the last one, which can hide mistakes in hand-edited config files. If duplicate keys are a realistic risk in your repo, add a specialized check instead of assuming a normal parser will catch them.
A Simple Decision Rule
- If the repository only stores occasional JSON config, start with a strict parser plus Prettier `--check`.
- If JSON drives runtime behavior, deployments, or test fixtures, add schema validation for those files.
- If the job is noisy or slow, narrow the file set before removing validation depth.
- If developers keep getting surprised by CI failures, add the same commands to a pre-commit hook or local `lint:json` script so the feedback happens earlier.
Conclusion
JSON linting in continuous integration pipelines works best when it is treated as a small stack of checks, not a single command. Parse validity protects you from broken syntax. Formatting checks keep diffs stable. Schema validation protects the files that can break production even when they are technically valid JSON. Put those pieces together and your CI job becomes a reliable guardrail instead of a vague "JSON check" that only catches the easiest mistakes.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool