Skip to content

Make json and junit reporters default output use .vitest as the report artifact root #10619

Description

@hi-ogawa

Problem

Vitest now documents .vitest/ as the shared location for generated reports and artifacts. The blob reporter already follows this (.vitest/blob/), but json and junit do not.

Currently, when no outputFile is configured:

  • json prints the report to stdout (json.ts:231-248)
  • junit prints the report to stdout (junit.ts:249-273)

This is inconsistent with the .vitest/ convention and with the blob reporter, and means these reporters produce no on-disk artifact by default.

In practice, "print to stdout" pushes users into awkward workarounds to get the file they actually wanted. Common patterns in the wild:

  • Redirect to a file, then upload as a CI artifact: vitest run --reporter=json > vitest-report.json then upload it (e.g. mizchi/flaker .github/workflows/ci.yml, which redirects → uploads → re-imports the report in a later job).
  • Pipe into a post-processor: vitest --reporter=json | jq '.numFailedTests'.
  • Redirect a bench/report run: vitest bench --run --reporter=json > benchmark-results.json (e.g. thibmeu/act-ts).

A scoped .vitest/ default serves all of these better, with zero config:

  • Artifact upload: just run vitest --reporter=json and upload .vitest/json/output.json — no redirect.
  • Post-analysis: jq '.numFailedTests' .vitest/json/output.json — and it's re-runnable without re-running the tests, since the artifact persists.

So the stdout default isn't a feature these workflows rely on; it's the limitation they work around. Moving to .vitest/ removes the workaround.

Goal

When the json and junit reporters use their default output (no outputFile), write to a scoped directory under .vitest/:

.vitest/
  json/
    output.json
  junit/
    output.xml

This mirrors the existing blob behavior (blob.ts:88-116): explicit outputFile always wins; otherwise fall back to createReport(scope) + a default filename.

Desired behavior

  • No outputFile configured:
    • json writes .vitest/json/output.json
    • junit writes .vitest/junit/output.xml
  • Explicit outputFile (string or outputFile.json / outputFile.junit) is respected and still resolved against root, unchanged.

Breaking change

The default changes from "print to stdout" to "write to file". This affects:

  • The documented piping workflow vitest --reporter=json > out.json (docs/guide/reporters.md:63-67, 319, 423).
  • Any CI that consumes json/junit from stdout.

Decision: drop stdout entirely; no sentinel opt-in. Every workflow stdout enabled (artifact upload, | jq post-processing) is served better by reading .vitest/json/output.json after a plain vitest --reporter=json. Adding an outputFile: 'stdout' sentinel would just preserve the worse path. Explicit outputFile (file path) is unchanged.

Scope / notes

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions