Skip to content

npm-compatible publication

The default publish path is npm-compatible. mx publish packs and uploads to whatever HTTP registry honors the npm protocol — HiveCast's Gitea-backed registry, an internal Verdaccio, GitHub Packages, etc.

The flow

  1. mx login writes a credential record. Source: packages/mx-cli/src/utils/auth-store.ts. Stored at <MATRIX_HOME>/credentials/registry.json by default (override with --credentials-file).
  2. mx publish resolves the registry URL (CLI flag → mx config → default https://registry.hivecast.ai/api/packages/open-matrix/npm/).
  3. Preflight passes (see Publishing → index).
  4. packNpmPublishTarball (packages/mx-cli/src/utils/npm-registry-client.ts:90-144) runs npm pack <package-dir> --pack-destination <outDir> and returns the tarball path.
  5. publishNpmTarball (packages/mx-cli/src/utils/npm-registry-client.ts:146-176) runs npm publish <tarballPath> --registry <url> --userconfig <tmp-npmrc>.
  6. The temp .npmrc carries the registry URL and the auth token; it is written to a mkdtemp directory and cleaned up after the command completes.

The CLI does not roll its own HTTP client for npm publishes. It shells out to the local npm binary because npm publish is the canonical implementation of the protocol.

Authentication

mx login --registry <url> --username <name> --token <token> writes a credential record:

json
{
  "registry": "https://registry.hivecast.ai/api/packages/open-matrix/npm/",
  "username": "richard.santomauro@nimbletec.com",
  "token": "<opaque token>",
  "expiresAt": "2027-05-05T12:00:00.000Z"
}

mx publish reads this record, writes it as _authToken in the temporary .npmrc:

//registry.hivecast.ai/api/packages/open-matrix/npm/:_authToken=<token>
always-auth=true
registry=https://registry.hivecast.ai/api/packages/open-matrix/npm/

The token never appears on the command line and is not persisted under your home ~/.npmrc.

Dry-run

bash
mx publish --dry-run

Runs preflight and pack but skips the publish call. Returns a JSON result with dryRun: true and tarballPath so you can inspect the artifact:

bash
mx publish --dry-run --json | jq .tarballPath
# /path/to/.mx-pack/npm/open-matrix-chat-0.2.9.tgz
tar -tzf /path/to/.mx-pack/npm/open-matrix-chat-0.2.9.tgz | head

What's in the tarball

npm pack honors:

  • package.json:files — explicit file allowlist
  • .npmignore if present
  • Default exclusions (.git, node_modules, .npmrc, *.log, etc.)
  • package.json:exports and main are not consulted; pack only cares about which files end up in the tarball

Always include the manifests and the built artifacts:

json
"files": [
  "dist/",
  "matrix.json",
  "matrix.service.json",
  "README.md",
  "LICENSE"
]

packages/system/package.json is the canonical example.

Common errors

ErrorCauseFix
MX_AUTH_REQUIRED: run 'mx login' before publishNo credential found for the resolved registryRun mx login with the right --registry
MX_MANIFEST_INVALID: runtime.entry does not existYou forgot to pnpm buildRun the build, then republish
MX_REGISTRY_PACK_FAILED: npm pack failednpm pack itself errored — usually permission or package.json parseRe-run npm pack directly to see the underlying error
MX_REGISTRY_PUBLISH_FAILED: failed to publish ...@... to ...Registry rejected the upload (auth, version conflict, rate limit)Check the appended npm publish output for the registry's specific code
MX_REGISTRY_INVALID: use either --registry or --registry-dir, not bothBoth flags passedPick one

See also

Source: projects/matrix-3/packages/mx-cli/src/utils/npm-registry-client.ts wraps npm pack and npm publish; packages/mx-cli/src/commands/publish.ts:128-153 is the npm-registry branch.