Skip to content

pnpm publish --json produces empty stdout in pnpm 11 (regression from pnpm 10) #11476

@AgentEnder

Description

@AgentEnder

Last pnpm version that worked

10.x (any version that delegated to the npm CLI for publish)

pnpm version

11.0.4

Code to reproduce the issue

Empirical reproduction of the regression (no other tooling required):

mkdir /tmp/pnpm-publish-json-repro && cd /tmp/pnpm-publish-json-repro
echo '{"name":"@scope/x","version":"0.0.1"}' > package.json
echo "x" > index.js

# pnpm 10.x (delegates to npm CLI) — produces JSON on stdout:
npx pnpm@10 publish --json --dry-run --no-git-checks --registry=https://example.invalid
# stdout:
# {
#   "id": "@scope/x@0.0.1",
#   "name": "@scope/x",
#   "version": "0.0.1",
#   "size": 211,
#   "filename": "scope-x-0.0.1.tgz",
#   ...
# }

# pnpm 11.x (native publish) — outputs literally 0 bytes on stdout:
npx pnpm@11 publish --json --dry-run --no-git-checks --registry=https://example.invalid
# stdout: (empty, 0 bytes)
# exit code: 0

Expected behavior

pnpm publish --json should emit machine-readable JSON describing the published package(s) on stdout, consistent with the documented --json flag and with pnpm 10.x behavior. The flag is still listed in pnpm publish --help ("Show information in JSON format"), so consumers reasonably expect output.

Actual behavior

pnpm publish --json produces zero bytes on stdout when publish succeeds (exit code 0). The flag is silently a no-op for pnpm publish in v11.

Root cause

In pnpm 10 and earlier, pnpm publish shelled out to the npm CLI, so --json was forwarded to npm and npm produced an npm-shaped JSON object on stdout (containing id, name, version, size, filename, files, etc.).

PR #10591 ("feat!: replace npm publish with libnpmpublish") replaced that passthrough with an in-process libnpmpublish call. In the new implementation:

  • The publish handler in releasing/commands/src/publish/publish.ts returns { exitCode?, manifest?, publishedManifest? } on success — never a string — so pnpm/src/main.ts writes nothing to stdout.
  • --json is declared in the publish command's cliOptionsTypes (json: Boolean) and documented in --help, but opts.json is never read in the publish handler.
  • The reporter that prints the human-readable 📦 … / Published … lines is correctly suppressed by the existing --json handling at pnpm/src/main.ts:184 (const printLogs = !config['parseable'] && !config['json']), so JSON would not be polluted by log output if the handler emitted any.

Net result: pnpm publish --json (success) → empty stdout → downstream tools that parse the JSON break.

Impact

This silently breaks any tooling that parses pnpm publish --json output. Concrete cases:

Precedent

The directly analogous regression pnpm -g ls --json (#11440) was treated and fixed as a regression in PR #11451 (merged 2026-05-04), with new tests asserting valid JSON output. The same expectation applies here: --json is a documented flag and consumers — including pnpm's own ecosystem (Nx, changesets-style flows) — depend on it producing parseable JSON.

Node.js version

24.11.0

Operating System

  • macOS
  • Linux
  • Windows

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions