Skip to content

# Use @openai/codex dist-tags for platform binaries instead of separate package names#11339

Merged
bolinfest merged 1 commit intomainfrom
pr11339
Feb 10, 2026
Merged

# Use @openai/codex dist-tags for platform binaries instead of separate package names#11339
bolinfest merged 1 commit intomainfrom
pr11339

Conversation

@bolinfest
Copy link
Collaborator

@bolinfest bolinfest commented Feb 10, 2026

#11318 introduced logic to publish platform artifacts as separate npm packages (for example, @openai/codex-darwin-arm64, @openai/codex-linux-x64, etc.). That requires provisioning and maintaining multiple package entries in npm, which we want to avoid.

We still need to keep the package-size mitigation (platform-specific payloads), but we want that layout to live under a single npm package namespace (@openai/codex) using dist-tags.

We also need to preserve pre-release workflows where users install @openai/codex@alpha and get platform-appropriate binaries.

Additionally, we want GitHub Release assets to group Codex npm tarballs together, so platform tarballs should follow the same codex-npm-* filename prefix as the main Codex tarball.

Release Strategy (New Scheme)

We publish one npm package name for Codex binaries (@openai/codex) and use dist-tags to select platform-specific payloads. This avoids creating separate platform package names while keeping the package size split by platform.

What gets published

Mainline release (x.y.z)

  • @openai/codex@latest (meta package)
  • @openai/codex@darwin-arm64
  • @openai/codex@darwin-x64
  • @openai/codex@linux-arm64
  • @openai/codex@linux-x64
  • @openai/codex@win32-arm64
  • @openai/codex@win32-x64
  • @openai/codex-responses-api-proxy@latest
  • @openai/codex-sdk@latest

Alpha release (x.y.z-alpha.N)

  • @openai/codex@alpha (meta package)
  • @openai/codex@alpha-darwin-arm64
  • @openai/codex@alpha-darwin-x64
  • @openai/codex@alpha-linux-arm64
  • @openai/codex@alpha-linux-x64
  • @openai/codex@alpha-win32-arm64
  • @openai/codex@alpha-win32-x64
  • @openai/codex-responses-api-proxy@alpha
  • @openai/codex-sdk@alpha

As an example, the package.json for @openai/codex@alpha (using 0.99.0-alpha.17 as the version) would be:

{
  "name": "@openai/codex",
  "version": "0.99.0-alpha.17",
  "license": "Apache-2.0",
  "bin": {
    "codex": "bin/codex.js"
  },
  "type": "module",
  "engines": {
    "node": ">=16"
  },
  "files": [
    "bin"
  ],
  "repository": {
    "type": "git",
    "url": "git+https://github.com/openai/codex.git",
    "directory": "codex-cli"
  },
  "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264",
  "optionalDependencies": {
    "@openai/codex-linux-x64": "npm:@openai/codex@0.99.0-alpha.17-linux-x64",
    "@openai/codex-linux-arm64": "npm:@openai/codex@0.99.0-alpha.17-linux-arm64",
    "@openai/codex-darwin-x64": "npm:@openai/codex@0.99.0-alpha.17-darwin-x64",
    "@openai/codex-darwin-arm64": "npm:@openai/codex@0.99.0-alpha.17-darwin-arm64",
    "@openai/codex-win32-x64": "npm:@openai/codex@0.99.0-alpha.17-win32-x64",
    "@openai/codex-win32-arm64": "npm:@openai/codex@0.99.0-alpha.17-win32-arm64"
  }
}

Note that the keys in optionalDependencies have "clean" names, but the values have the tag embedded.

Important note

Note: Because we never created the new platform package names on npm (for example,
@openai/codex-darwin-arm64) since #11318 landed, there are no extra npm packages to clean up.

What changed

1. Stage platform tarballs as @openai/codex with platform-specific versions

File: codex-cli/scripts/build_npm_package.py

  • Added CODEX_NPM_NAME = "@openai/codex" and platform metadata npm_tag values:
    • darwin-arm64, darwin-x64, linux-arm64, linux-x64, win32-arm64, win32-x64
  • For platform package staging (codex-<platform> inputs), switched generated package.json from:
    • name = @openai/codex-<platform>
      to:
    • name = @openai/codex
  • Added compute_platform_package_version(version, platform_tag) so platform tarballs have unique
    versions (<release-version>-<platform-tag>), which is required because npm forbids re-publishing
    the same name@version.

2. Point meta package optional dependencies at dist-tags on @openai/codex

File: codex-cli/scripts/build_npm_package.py

  • Updated optionalDependencies generation for the main codex package to use npm alias syntax:
    • key remains alias package name (for example, @openai/codex-darwin-arm64) so runtime lookup behavior is unchanged
    • value now resolves to @openai/codex by dist-tag
  • Stable releases emit tags like npm:@openai/codex@darwin-arm64.
  • Alpha releases (x.y.z-alpha.N) emit tags like npm:@openai/codex@alpha-darwin-arm64.

3. Publish with per-tarball dist-tags in release CI

File: .github/workflows/rust-release.yml

  • Reworked npm publish logic to derive the publish tag per tarball filename:
    • platform tarballs publish with <platform> tags for stable releases
    • platform tarballs publish with alpha-<platform> tags for alpha releases
    • top-level tarballs (codex, codex-responses-api-proxy, codex-sdk) continue using
      the existing channel tag policy (latest implicit for stable, alpha for alpha)
  • Added fail-fast behavior for unexpected tarball names to avoid silent mispublishes.

4. Normalize Codex platform tarball filenames for GitHub Release grouping

Files: scripts/stage_npm_packages.py, .github/workflows/rust-release.yml

  • Renamed staged platform tarball filenames from:
    • codex-linux-<arch>-npm-<version>.tgz
    • codex-darwin-<arch>-npm-<version>.tgz
    • codex-win32-<arch>-npm-<version>.tgz
  • To:
    • codex-npm-linux-<arch>-<version>.tgz
    • codex-npm-darwin-<arch>-<version>.tgz
    • codex-npm-win32-<arch>-<version>.tgz

This keeps all Codex npm artifacts grouped under a common codex-npm- prefix in GitHub Releases.

5. Documentation update

File: codex-cli/scripts/README.md

  • Updated staging docs to clarify that platform-native variants are published as dist-tagged
    @openai/codex artifacts rather than separate npm package names.

Resulting behavior

  • Mainline release:
    • @openai/codex@latest resolves the meta package
    • meta package optional dependencies resolve @openai/codex@<platform-tag>
  • Alpha release:
    • users can continue installing @openai/codex@alpha
    • alpha meta package optional dependencies resolve @openai/codex@alpha-<platform-tag>
  • Release assets:
    • Codex npm tarballs share codex-npm- prefix for cleaner grouping in GitHub Releases

This preserves platform-specific payload distribution while avoiding separate npm package names and
improves release-asset discoverability.

Validation notes

  • Verified staged package.json output for stable and alpha meta packages includes expected alias targets.
  • Verified staged platform package manifests are name=@openai/codex with unique platform-suffixed versions.
  • Verified publish tag derivation maps renamed platform tarballs to expected stable and alpha dist-tags.

@bolinfest bolinfest requested a review from jif-oai February 10, 2026 17:56
Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3654a194d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +310 to +311
f"npm:{CODEX_NPM_NAME}@"
f"{compute_platform_dist_tag(version, CODEX_PLATFORM_PACKAGES[platform_package]['npm_tag'])}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pin platform optional deps to immutable versions

stage_sources now emits optionalDependencies as npm:@openai/codex@<dist-tag> instead of a concrete version, and those tags are repointed on every release (.github/workflows/rust-release.yml publishes platform tarballs with fixed tags like linux-x64 / alpha-linux-x64). Since dist-tags are mutable, installing an older pinned meta package (for example @openai/codex@1.2.3) after a newer release will pull newer platform binaries, which breaks reproducible installs and can mismatch launcher/binary versions.

Useful? React with 👍 / 👎.

CODEX_SDK_ROOT = REPO_ROOT / "sdk" / "typescript"
CODEX_NPM_NAME = "@openai/codex"

# `npm_name` is the local optional-dependency alias consumed by `bin/codex.js`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we drop it then/

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is accurate. In the PR body, I added the package.json we should expect. As we can see npm_name here is the key in "optionalDependencies", the naming of which codex.js depends on here:

"x86_64-unknown-linux-musl": "@openai/codex-linux-x64",
"aarch64-unknown-linux-musl": "@openai/codex-linux-arm64",
"x86_64-apple-darwin": "@openai/codex-darwin-x64",
"aarch64-apple-darwin": "@openai/codex-darwin-arm64",
"x86_64-pc-windows-msvc": "@openai/codex-win32-x64",
"aarch64-pc-windows-msvc": "@openai/codex-win32-arm64",

And that will be the subdirectory under node_modules where things should be found, I believe?

return f"alpha-{platform_tag}" if is_alpha_release(version) else platform_tag


def compute_platform_package_version(version: str, platform_tag: str) -> str:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would inline this

return re.match(r"^[0-9]+\.[0-9]+\.[0-9]+-alpha\.[0-9]+$", version) is not None


def compute_platform_dist_tag(version: str, platform_tag: str) -> str:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would inline this

…rate package names

#11318 introduced logic to publish platform artifacts as separate npm packages (for example,
`@openai/codex-darwin-arm64`, `@openai/codex-linux-x64`, etc.). That requires provisioning and
maintaining multiple package entries in npm, which would be nice to avoid.

We still need to keep the package-size mitigation (platform-specific payloads), but we want that
layout to live under a single npm package namespace (`@openai/codex`) using dist-tags.

We also need to preserve pre-release workflows where users install `@openai/codex@alpha` and get
platform-appropriate binaries.

## Release Strategy (New Scheme)

We publish **one npm package name for Codex binaries** (`@openai/codex`) and use **dist-tags** to select platform-specific payloads.
This avoids creating separate platform package names while keeping the package size split by platform.

### What gets published

#### Mainline release (`x.y.z`)

- `@openai/codex@latest` (meta package)
- `@openai/codex@darwin-arm64`
- `@openai/codex@darwin-x64`
- `@openai/codex@linux-arm64`
- `@openai/codex@linux-x64`
- `@openai/codex@win32-arm64`
- `@openai/codex@win32-x64`
- `@openai/codex-responses-api-proxy@latest`
- `@openai/codex-sdk@latest`

#### Alpha release (`x.y.z-alpha.N`)

- `@openai/codex@alpha` (meta package)
- `@openai/codex@alpha-darwin-arm64`
- `@openai/codex@alpha-darwin-x64`
- `@openai/codex@alpha-linux-arm64`
- `@openai/codex@alpha-linux-x64`
- `@openai/codex@alpha-win32-arm64`
- `@openai/codex@alpha-win32-x64`
- `@openai/codex-responses-api-proxy@alpha`
- `@openai/codex-sdk@alpha`

### Important note

**Note:** Because we never created the new packages on npm for, e.g., `@openai/codex-darwin-arm64`, since #11318 was merged, there are no npm packages to "clean up" as a result of this change.

## What changed

### 1. Stage platform tarballs as `@openai/codex` with platform-specific versions

File: `codex-cli/scripts/build_npm_package.py`

- Added `CODEX_NPM_NAME = "@openai/codex"` and platform metadata `npm_tag` values:
  - `darwin-arm64`, `darwin-x64`, `linux-arm64`, `linux-x64`, `win32-arm64`, `win32-x64`
- For platform package staging (`codex-<platform>` inputs), switched generated `package.json` from:
  - `name = @openai/codex-<platform>`
    to:
  - `name = @openai/codex`
- Added `compute_platform_package_version(version, platform_tag)` to make platform tarball versions unique
  (`<release-version>-<platform-tag>`), because npm does not allow publishing the same `name@version`
  repeatedly for multiple platform artifacts.

### 2. Point meta package optional dependencies at dist-tags on `@openai/codex`

File: `codex-cli/scripts/build_npm_package.py`

- Updated `optionalDependencies` generation for the main `codex` package to use npm alias syntax:
  - key remains alias package name (e.g. `@openai/codex-darwin-arm64`), preserving runtime lookup behavior
  - value now resolves to `@openai/codex` by dist-tag
- Stable releases now emit:
  - `npm:@openai/codex@darwin-arm64`, etc.
- Alpha releases (`x.y.z-alpha.N`) now emit:
  - `npm:@openai/codex@alpha-darwin-arm64`, etc.

### 3. Publish with per-tarball dist-tags in release CI

File: `.github/workflows/rust-release.yml`

- Reworked npm publish step to derive publish tag per tarball filename:
  - platform tarballs publish with `<platform>` tags for stable releases
  - platform tarballs publish with `alpha-<platform>` tags for alpha releases
  - top-level tarballs (`codex`, `codex-responses-api-proxy`, `codex-sdk`) continue using the release tag policy
    (`latest` implicit for stable, `alpha` for alpha)
- Added fail-fast behavior for unexpected tarball names to avoid silent mispublishes.

### 4. Documentation update

File: `codex-cli/scripts/README.md`

- Updated release staging description to reflect that platform-native variants are published as
  dist-tagged `@openai/codex` artifacts rather than separate npm package names.

## Resulting behavior

- Mainline release:
  - `@openai/codex@latest` resolves meta package
  - meta package optional deps reference `@openai/codex@<platform-tag>`
- Alpha release:
  - users can continue installing `@openai/codex@alpha`
  - alpha meta package optional deps reference `@openai/codex@alpha-<platform-tag>`

This preserves platform-specific payload distribution while eliminating the need to manage a separate npm
package per platform.

## Validation notes

- Verified staged `package.json` output for stable and alpha meta packages includes expected alias targets.
- Verified staged platform package manifests are `name=@openai/codex` with unique platform-suffixed versions.
- Verified release publish tag derivation logic maps tarball names to expected stable and alpha platform tags.
@bolinfest bolinfest merged commit d9c014e into main Feb 10, 2026
60 of 64 checks passed
@bolinfest bolinfest deleted the pr11339 branch February 10, 2026 18:33
@github-actions github-actions bot locked and limited conversation to collaborators Feb 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants