Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool

Using JSON Formatters in CI/CD Pipelines

The most reliable pattern is simple: format JSON locally, then fail CI if anything reaches the pipeline unformatted. In practice that usually means running Prettier with --write on developer machines and --check in CI. If you only need syntax validation or want to re-indent generated JSON in a shell step, jq is still a useful option.

This guide focuses on what a search visitor usually needs: which command to run, where it belongs in the pipeline, what to ignore, and how to avoid common CI failures.

Recommended Setup

  • Install a formatter in the repository so every developer and CI job uses the same version.
  • Run prettier --write locally or in a pre-commit hook to fix files before they are pushed.
  • Run prettier --check in CI so pull requests fail instead of silently reformatting code.
  • Commit a .prettierignore file so generated, vendored, or snapshot JSON does not create noise.
  • Use jq for generated artifacts or validation-only shell steps, not as a replacement for repo-wide style policy.

Pick the Right Tool

For most application repositories, Prettier is the better default because it gives you one consistent style for JSON and other text formats in the same codebase. It is especially useful when your repository already contains JavaScript, TypeScript, Markdown, YAML, or JSON configuration.

jq is better suited to shell-heavy workflows: validating incoming JSON, reformatting machine-made files during builds, or inspecting pipeline output while debugging. It pretty-prints JSON by default, but it is not a team-wide formatting policy tool in the same way Prettier is.

Whichever tool you choose, remember the boundary: formatting catches syntax and layout problems, but it does not replace schema validation or application tests.

Check Mode vs Write Mode

This is the core distinction to get right. Use --write where it is safe to modify files. Use --check where you want the job to fail and force the change back into the branch.

Typical commands

# Fix files locally
npx prettier . --write

# Fail CI if formatting drift is found
npx prettier . --check

# Target JSON-family files only
npx prettier "**/*.{json,jsonc,json5}" --check

Prettier recommends quoting globs so the command behaves consistently across shells and operating systems.

If your pipeline uses npm, pnpm, or yarn, prefer the project-local binary rather than downloading a transient formatter version during the build. That keeps local runs and CI results aligned.

Pre-Commit Hooks Keep CI Quiet

CI should be the enforcement layer, not the first place developers discover formatting issues. A pre-commit hook fixes the easy cases before they become failed pull requests.

If you use pre-commit, a local hook is a clean way to run the formatter already installed in your repository:

Example .pre-commit-config.yaml

repos:
  - repo: local
    hooks:
      - id: prettier-json
        name: prettier json
        language: system
        entry: npx prettier --write
        files: \.(json|jsonc|json5)$

This relies on the project's installed Prettier version and only rewrites matching JSON files before the commit is created.

If your team does not use pre-commit, the same idea works with Husky, lefthook, or any other Git-hook manager: run --write before the commit, then keep --check in CI as the hard gate.

Minimal GitHub Actions Job

The exact CI provider matters less than the command. GitHub Actions is a common example, and the same pattern maps directly to GitLab CI, CircleCI, Jenkins, or Buildkite: install dependencies, then run the formatter in check mode.

Example workflow

name: json-format-check

on:
  pull_request:
  push:
    branches: [main]
    paths:
      - "**/*.json"
      - "**/*.jsonc"
      - "**/*.json5"
      - ".prettier*"
      - "package.json"
      - "package-lock.json"

jobs:
  prettier:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Install dependencies
        run: npm ci

      - name: Check JSON formatting
        run: npx prettier "**/*.{json,jsonc,json5}" --check

The paths filter keeps unrelated pushes from running the job, which matters in larger repositories.

For non-GitHub systems, keep the shell commands and drop the provider-specific YAML. That gives you the same enforcement behavior without changing the underlying workflow design.

When jq Is the Better Fit

jq is ideal when a build step produces JSON and you want to validate or normalize it immediately. It also works well in slim environments where adding the full JavaScript toolchain would be excessive.

Useful jq patterns

# Validate JSON syntax in a CI step
jq . build/output.json > /dev/null

# Reformat a generated file safely
tmp_file="$(mktemp)"
jq . build/output.json > "$tmp_file" && mv "$tmp_file" build/output.json

Write to a temporary file and move it into place. Redirecting output back into the same file will truncate it.

The main limitation is that jq only knows about JSON structure. It will not apply the same repository-wide style rules you use for other files, and it will not decide which generated directories should be excluded from checks.

Common CI/CD Mistakes

  • Auto-fixing in CI: A formatter that rewrites files during CI hides the problem. For pull requests, failing fast with --check is usually cleaner.
  • Formatting generated output: Exclude build artifacts, vendored content, and snapshots with .prettierignore unless they are intentionally committed and reviewed.
  • Unquoted globs: Shell expansion differs across environments. Quote file patterns to avoid "works on my machine" failures.
  • Expecting formatting to validate meaning: A formatter can catch malformed JSON, but it will not tell you whether the keys, types, or values are correct for your application.
  • Running on the whole monorepo by default: Scope the job to relevant directories or changed paths if runtime becomes noticeable.

Conclusion

A good JSON formatting pipeline is deliberately boring: fix locally, check in CI, ignore the files that should stay out of scope, and use jq only where shell-oriented JSON handling is actually the goal. That setup keeps diffs clean, catches broken JSON early, and removes format arguments from code review without overcomplicating the pipeline.

Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool