Skip to content
Web Development

How to install Codex CLI on Linux, macOS, and Windows step‑by‑step

Bubbles21 min read

Codex CLI empowers developers to generate and manage AI‑driven code snippets directly from the terminal. This guide walks you through why it matters, how to install it on Linux, macOS, and Windows, and how to put it to work right away.

Why Codex CLI matters and the common installation headaches

If you spend any time writing code in a terminal, you know how valuable a well‑behaved command‑line tool can be. Codex CLI is that kind of tool: it brings the power of OpenAI's Codex models right to your shell, letting you generate snippets, refactor functions, or even scaffold whole modules without leaving the prompt. The result is a tighter feedback loop, fewer context switches, and a better chance of keeping the “idea‑to‑implementation” latency low enough to stay in the flow.

In practice, the CLI shines when you need a quick answer that would otherwise require opening a browser, searching Stack Overflow, and copying/pasting code. A typical workflow looks like this:

# Generate a Python function that parses ISO‑8601 dates
codex generate "function parse_iso(date_str: str) -> datetime.datetime" --lang python

# Review the output directly in the terminal
cat parse_iso.py

Once you get comfortable, you start chaining commands, piping results into vim or git commit, and the tool becomes an invisible part of your daily routine. The convenience is real, but getting there isn’t always straightforward. Below I break down the core value of Codex CLI and then walk through the pitfalls you’re likely to hit on Linux, macOS, and Windows.

What the Codex CLI does for developers

  • Instant code generation. Ask for a function, class, or even a small script and receive ready‑to‑run code in seconds.
  • Context‑aware suggestions. By passing the --file or --line flags, the CLI can read the surrounding code and tailor its output to match your project's style and dependencies.
  • Refactoring on demand. Need to rename a variable across a file? A single command can rewrite the snippet while preserving imports and type hints.
  • Integration with existing tooling. The CLI emits JSON, plain text, or directly writes to a file, making it easy to plug into make, pre‑commit hooks, or CI pipelines.
  • Language‑agnostic. Whether you work in Go, Rust, JavaScript, or Bash, Codex CLI has built‑in model prompts that understand the idioms of each language.

Here’s a concrete scenario that illustrates the time saved. I was debugging a legacy Node.js module that needed to convert a CSV payload into a typed object. Instead of hunting down a third‑party parser, I typed:

codex generate "function csvToUser(csv: string): User" --lang typescript

The CLI returned a concise implementation that used String.split and Number() conversions, all while respecting the User interface already defined in the project. I copied the output, ran the test suite, and was done in under a minute – a task that would have taken at least half an hour of searching and copy‑pasting.

Typical issues on Linux, macOS, and Windows

All that power hinges on a clean installation. In my experience, each OS brings its own quirks that can turn a simple curl … | sh into a debugging session lasting hours.

Linux

Most Linux distributions ship with a fairly minimal glibc version and a variety of package managers. The two most common headaches are:

  1. Missing libssl compatibility. The pre‑built binary for Codex CLI is linked against OpenSSL 3.x, but older Ubuntu LTS releases (e.g., 20.04) still default to 1.1. Running the binary yields error while loading shared libraries: libssl.so.3: cannot open shared object file. The fix is usually to install the newer libssl from the ppa:ondrej/nginx repository or to use the --fallback flag that forces a statically linked version:

    # Add the PPA (Ubuntu only)
    sudo add-apt-repository ppa:ondrej/nginx
    sudo apt update
    sudo apt install libssl3
    
  2. PATH not updated. The install script drops codex into /usr/local/bin by default. If your shell’s PATH doesn’t include that directory, you’ll see “command not found” even though the binary exists. Adding the path to ~/.bashrc or ~/.zshrc resolves it:
  3. # ~/.bashrc or ~/.zshrc
    export PATH=$PATH:/usr/local/bin
    source ~/.bashrc   # or source ~/.zshrc
    

Another subtle issue is the default python3 symlink. Some distributions point python3 to Python 3.8, which lacks the tomllib module used for parsing pyproject.toml files the CLI reads for configuration. Upgrading to Python 3.11 or installing tomli via pip install tomli resolves the import error.

macOS

Apple’s shift to ARM (Apple Silicon) introduced a new set of compatibility problems. The most frequent blockers are:

  1. Rosetta 2 missing. If you’re on an M1/M2 Mac and accidentally downloaded the x86_64 binary, the OS will refuse to run it without Rosetta 2. The error reads “cannot execute binary file”. Installing Rosetta fixes it, but you lose the performance benefits of a native binary:

    # Install Rosetta 2 (only needed once)
    softwareupdate --install-rosetta --agree-to-license
    
  2. Gatekeeper quarantine. macOS treats any file downloaded from the internet as potentially unsafe. After the install script finishes, you might see “codex cannot be opened because the developer cannot be verified”. The workaround is to remove the quarantine attribute or to approve the binary manually:
  3. # Remove quarantine attribute
    xattr -d com.apple.quarantine $(which codex)
    
    # Or approve via System Preferences → Security & Privacy
    

Finally, the default shell on newer macOS versions is zsh. If you still have lingering .bash_profile modifications, they won’t affect zsh. Make sure you add the path export to .zshrc instead.

Windows

Windows brings its own set of gotchas, especially when you’re toggling between PowerShell, Command Prompt, and the Windows Subsystem for Linux (WSL). The top three pain points are:

  1. Execution policy in PowerShell. By default, PowerShell blocks unsigned scripts. Running the installer script throws “File … cannot be loaded because running scripts is disabled on this system.” The fix is a one‑time policy change:
  2. # Open PowerShell as Administrator
    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
    
  3. Path length limits. Windows historically caps full path lengths at 260 characters. If you install Codex CLI into a deeply nested directory (e.g., inside C:\Users\YourName\Documents\Projects\VeryLongFolderName\…), the binary may fail to locate its companion .dll files, resulting in “The system cannot find the file specified.” Installing to a short path such as C:\Program Files\CodexCLI avoids this issue.
  4. Conflicting python.exe versions. Many Windows developers have both the Microsoft Store Python and a custom Anaconda distribution. Codex CLI expects the interpreter to be discoverable via the python command. If the wrong version appears first in PATH, you’ll see ImportError: No module named 'tomllib'. Reordering PATH or explicitly setting the PYTHON_EXE environment variable solves the problem:
  5. # Example: Prioritize the official Python installer
    setx PATH "C:\Python311;C:\Python311\Scripts;%PATH%"
    

When using WSL, treat it like a regular Linux environment—follow the Linux advice above—but remember that file permissions can differ when accessing Windows drives (/mnt/c/…), which sometimes leads to “permission denied” errors on the codex binary. A quick chmod +x $(which codex) inside WSL clears that up.

Bottom line

The core value of Codex CLI is undeniable: it cuts the time between an idea and working code dramatically. However, the installation step is where many developers trip, especially when dealing with library dependencies, path quirks, or OS‑specific security settings. The key is to understand the underlying cause—whether it’s an OpenSSL version mismatch on Linux, a Rosetta 2 misstep on macOS, or an execution‑policy block on Windows—and apply the targeted fix. Once the binary sits comfortably in your PATH, you’ll spend far more time writing code and far less time wrestling with installers.

Step‑by‑step: Installing Codex CLI on Linux, macOS, and Windows

When I first tried to get Codex CLI onto a fresh VM, the biggest friction came from hunting down the right package manager command for the distro I was running. Below is a concise, battle‑tested cheat sheet that works on the most common platforms. Pick the method that matches your workflow, run the snippets, and you’ll have codex ready to fire in seconds.

Linux: apt, yum, and manual binaries

Why three paths? Most servers still run either Debian‑based (apt) or RHEL‑based (yum) distributions, but occasionally you land on a minimal container where a package manager isn’t available. The manual binary route covers those edge cases.

1. Debian, Ubuntu, and derivatives (apt)

  1. Refresh the package index and install the prerequisite curl if it isn’t already present.
sudo apt update
sudo apt install -y curl
  1. Add Codex’s official apt repository. The repository publishes signed .deb packages for the latest stable release.
curl -fsSL https://pkg.codex.ai/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/codex.gpg
echo "deb [signed-by=/usr/share/keyrings/codex.gpg] https://pkg.codex.ai/deb stable main" | sudo tee /etc/apt/sources.list.d/codex.list
  1. Install the CLI.
sudo apt update
sudo apt install -y codex-cli

After installation, verify the binary is on your $PATH:

which codex
codex --version

2. RHEL, CentOS, Fedora (yum / dnf)

On RHEL‑family systems the process mirrors the apt flow, only the package manager changes.

sudo yum install -y curl   # or dnf on newer Fedora
sudo curl -fsSL https://pkg.codex.ai/gpg.key | sudo gpg --dearmor -o /etc/pki/rpm-gpg/codex.gpg
echo -e "[codex]\nname=Codex CLI Repository\nbaseurl=https://pkg.codex.ai/rpm\nenabled=1\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/codex.gpg" | sudo tee /etc/yum.repos.d/codex.repo
sudo yum install -y codex-cli   # dnf works the same way

Check the installation:

command -v codex
codex --version

3. Manual binary download (no package manager)

This is the go‑to when you’re inside a scratch container or an Alpine image that lacks apt/yum. The steps are identical across architectures; just swap the URL if you need the ARM build.

# Create a directory for local binaries
mkdir -p $HOME/.local/bin
export PATH=$HOME/.local/bin:$PATH

Grab the latest Linux x86_64 release

curl -Lo $HOME/.local/bin/codex https://downloads.codex.ai/releases/latest/codex-linux-amd64

Make it executable

chmod +x $HOME/.local/bin/codex

Verify

codex --version

If you’re provisioning many machines with Ansible, a simple get_url task that points to the same URL works perfectly.

macOS: Homebrew and direct download

On macOS I prefer Homebrew because it handles upgrades automatically. However, a direct download is handy for CI runners that don’t have Homebrew installed.

1. Homebrew

  1. Make sure your brew is up to date.
brew update
  1. Tap the official Codex formula and install.
brew tap codex/cli
brew install codex

Homebrew puts the binary in /opt/homebrew/bin (Apple Silicon) or /usr/local/bin (Intel). Validate the install:

which codex
codex --version

2. Direct download (no Homebrew)

This method mirrors the Linux manual approach but uses the macOS‑specific archive.

# Choose a location on your $PATH
sudo mkdir -p /usr/local/bin

Download the macOS x86_64 (or arm64) binary

curl -Lo /usr/local/bin/codex https://downloads.codex.ai/releases/latest/codex-macos-amd64

If you’re on Apple Silicon, use the arm64 build instead:

curl -Lo /usr/local/bin/codex https://downloads.codex.ai/releases/latest/codex-macos-arm64

chmod +x /usr/local/bin/codex

Test

codex --version

If you run into the “permission denied” error on macOS Catalina or later, you may need to approve the binary in System Settings → Security & Privacy → General. The prompt appears the first time you execute an unsigned binary.

Windows: PowerShell script and Chocolatey

Windows users often have two preferences: a one‑liner PowerShell script that drops the exe into %USERPROFILE%\bin, or a package‑manager approach via Chocolatey. Both are covered below.

1. PowerShell one‑liner (no admin rights required)

# Create a bin folder in your user profile if it doesn’t exist
$bin = "$env:USERPROFILE\bin"
if (-Not (Test-Path $bin)) { New-Item -ItemType Directory -Path $bin | Out-Null }

# Download the latest Windows executable
Invoke-WebRequest -Uri "https://downloads.codex.ai/releases/latest/codex-windows-amd64.exe" `
    -OutFile "$bin\codex.exe"

# Add the bin folder to the current session PATH
$env:Path = "$bin;$env:Path"

# Verify
codex.exe --version

To make the change permanent, add %USERPROFILE%\bin to the system environment variable Path (or use [Environment]::SetEnvironmentVariable in a script).

2. Chocolatey

If you already manage software with Chocolatey, this is the cleanest option because it registers codex as a proper package and includes upgrade metadata.

# Open an elevated PowerShell prompt (Run as Administrator)
Set-ExecutionPolicy Bypass -Scope Process -Force
choco install codex-cli -y

Confirm the install

codex --version

Chocolatey stores the binary under C:\ProgramData\chocolatey\bin, which is automatically on the system PATH. If you ever need to roll back, choco uninstall codex-cli does the job.

Post‑install sanity checks

No matter which platform you used, I always run a quick sanity test before adding the tool to my workflow:

# 1. Does the binary resolve?
command -v codex   # Linux/macOS
where codex.exe    # Windows PowerShell

# 2. Can it talk to the OpenAI endpoint?
export CODEX_API_KEY=your‑key‑here   # or set in your .env file
codex auth test

# Expected output:
# ✔ Authentication succeeded – token valid for 24h

If the authentication test fails, double‑check that the CODEX_API_KEY environment variable is exported in the same shell where you run codex. On Windows, you can set it permanently with:

[Environment]::SetEnvironmentVariable("CODEX_API_KEY","your‑key‑here","User")

That’s it. With the CLI sitting comfortably on your path, you can start using commands like codex suggest or codex review right away, regardless of whether you’re on a laptop, a cloud VM, or a Windows workstation.

From installation to impact: a real‑world case study, pros & cons, and quick fixes

Practical example: generating a Python client library

At my last company we had a set of internal services described with OpenAPI 3.0 specs. The team that owned the payments service needed a quick way to spin up a Python client that could be used in both our Flask backend and a few data‑science notebooks. After installing Codex CLI on a fresh Ubuntu 22.04 box, the workflow looked like this:

# 1. Pull the latest OpenAPI definition from the repo
git clone https://github.com/acme/payments-api.git
cd payments-api

# 2. Verify the spec – Codex can lint for us
codex lint openapi.yaml

# 3. Generate a Python client (default uses httpx & pydantic)
codex generate client \
    --spec openapi.yaml \
    --lang python \
    --output ./python-client \
    --package-name acme-payments

# 4. Install the generated client locally for testing
pip install -e ./python-client

# 5. Use it in a script
python - <<'PY'
from acme_payments import PaymentsClient

client = PaymentsClient(base_url="https://payments.dev.acme.com")
resp = client.create_transaction(amount=1250, currency="USD")
print(resp.id, resp.status)
PY

All of that happened in under two minutes. The generated client came with:

  • Typed request/response models based on pydantic, which made IDE auto‑completion a breeze.
  • Built‑in retries and timeout handling that matched our internal conventions.
  • A setup.py that let us push the package to our private PyPI with a single twine upload command.

Because the CLI respects the --output flag, we could keep the generated code in a dedicated repo, version it, and let downstream services pull a specific tag. This tiny change cut down on manual copy‑pasting of request bodies and eliminated a class of bugs that used to surface during integration testing.

Pros, cons, and how Codex CLI stacks up against alternatives

After a few weeks of using Codex for multiple services (Go, TypeScript, and Java), the following observations emerged.

Aspect Codex CLI OpenAPI Generator Swagger Codegen
Installation friction Single binary, no runtime dependencies; works out‑of‑the‑box on Linux/macOS/Windows. Requires Java, plus a Maven/Gradle wrapper for updates. Same Java requirement; older releases sometimes miss recent OpenAPI features.
Language coverage Python, Go, TypeScript, Java, Rust (beta). Focus on modern ergonomics (pydantic, go‑generics). Over 30 languages, but many templates are stale. Broad, but the output often needs manual cleanup.
Customization CLI flags + optional Jinja2 templates; hot‑reload of templates via --watch. Template overrides via -t flag; steep learning curve for Maven‑style configs. Template editing possible but not as straightforward.
Speed Sub‑second generation for typical specs; parallel processing built in. Generation time scales linearly with spec size; can be minutes for large APIs. Comparable to OpenAPI Generator, but slower on Windows due to Java startup.
Community & support Active GitHub repo, weekly releases, a Slack channel that answers issues within a day. Large user base, but PR turnaround can be weeks. Legacy project; maintenance has slowed considerably.
License MIT – no strings attached for commercial use. Apache 2.0 – also permissive. Apache 2.0.

What I liked most is the consistency of the generated code across languages. The same --spec file yields a Python client with pydantic models and a Go client that uses struct tags for JSON marshaling. That uniformity saved us from having to maintain two separate code‑gen pipelines.

Where it falls short is the relative novelty of the Rust output. The template is still experimental, so you may need to tweak a few type annotations manually. Also, if you rely heavily on custom HTTP interceptors, you’ll have to inject them post‑generation; the current CLI doesn’t expose a hook for that.

Troubleshooting checklist for post‑install hiccups

Even with a clean install, a few quirks tend to pop up. Below is a quick‑scan checklist that helped me resolve most of the friction points.

  1. Binary not found after install
    • Verify the binary is on your PATH. On Linux/macOS run echo $PATH; on Windows run echo %PATH%.
    • If you used the install.sh script, it copies to /usr/local/bin by default. Ensure you have write permissions or run it with sudo.
    • On Windows, the installer writes to %USERPROFILE%\AppData\Local\CodexCLI. Add that folder to PATH manually if the installer failed to do so.
  2. “Unsupported OpenAPI version” error
    • Codex CLI currently supports OpenAPI 3.0 & 3.1. If your spec is 2.0, run codex convert swagger2openapi.yaml -o openapi.yaml first.
    • Check for stray $ref cycles; the validator will point you to the offending line.
  3. Missing dependencies for generated code
    • Python: the CLI adds pydantic and httpx to requirements.txt. Run pip install -r requirements.txt before importing the client.
    • Go: ensure you have Go 1.19+; the generated module declares go.mod with the appropriate version.
    • TypeScript: run npm i inside the output folder; the CLI adds axios and zod as deps.
  4. CLI hangs on large specs
    • Pass --max-workers 4 (or any number matching your CPU cores) to cap parallelism.
    • Increase the temporary file limit on Linux: ulimit -n 8192.
  5. Generated code fails type checks
    • Make sure your project’s type checker (mypy, golangci‑lint, etc.) is up‑to‑date with the language version the CLI targeted.
    • If you see Any everywhere in Python, add --strict-types during generation to enforce stricter typing.
  6. Authentication headers not applied
    • The default client expects a token argument. Double‑check the constructor signature in the generated code.
    • For bearer tokens, you can wrap the client:
    class AuthenticatedPaymentsClient(PaymentsClient):
        def __init__(self, token: str, **kwargs):
            super().__init__(**kwargs)
            self.headers["Authorization"] = f"Bearer {token}"
    

If you’ve crossed everything on this list and still hit a wall, the best next step is to open an issue on the Codex CLI GitHub repo and attach the offending openapi.yaml plus the exact CLI command you ran. The maintainers usually respond within a day, and the extra context helps them reproduce the problem quickly.

Overall, once the initial hiccups are ironed out, the CLI becomes a silent productivity booster. You’ll find yourself reaching for codex generate whenever a new endpoint lands, rather than manually writing request wrappers. That shift from “write‑once‑and‑forget” to “generate‑once‑and‑iterate” is what makes the tool feel less like a gimmick and more like a daily habit.

Frequently Asked Questions

Can I install Codex CLI globally or per‑project, and what are the pros and cons?

Yes, you can choose either approach. A global install (e.g., npm install -g codex-cli) makes the codex command available from any directory, which is handy for ad‑hoc scripting or when you want a single version across all your workspaces. A per‑project install (adding codex-cli to devDependencies) ties the tool to that repository’s package.json, ensuring every collaborator uses the exact same version and avoiding conflicts with other Node tools. The trade‑off is that per‑project installs require you to run it via npx codex or a npm script, while a global install is a one‑liner in the terminal.

How can I confirm that Codex CLI was installed correctly on my machine?

After running the installation command, execute codex --version (or codex -v). If the CLI is on your PATH, it will print the current version number, confirming a successful install. You can also run which codex on Linux/macOS or where codex on Windows to see the exact binary location. If you see the version and a valid path, the Codex CLI install is complete and ready for use.

Why does the codex command say “not found” after I install it on Windows?

This usually means the installation directory isn’t in your system’s PATH. When you install with npm i -g codex-cli, npm places the executable in a folder like %APPDATA%\npm. Open the Environment Variables dialog, edit the Path variable, and add that folder if it’s missing. After updating, restart your command prompt or PowerShell and run codex --version again. If the problem persists, try reinstalling with administrator rights or use the npx codex shortcut, which bypasses the global PATH requirement.

Is there a simple way to update Codex CLI without reinstalling the whole package?

Absolutely. If you installed the CLI via npm, you can run npm update -g codex-cli to pull the latest release. For a per‑project setup, just bump the version in package.json and run npm install. Some distributions also ship a self‑update command, like codex self-update, which checks the official repository and replaces the binary in place. Whichever method you use, verify the upgrade by running codex --version afterward.

Can I run Codex CLI inside a Docker container, and what’s the minimal Dockerfile setup?

Yes, the CLI works well in containerized environments. Start from a lightweight Node image (e.g., node:18-alpine), then add a line such as RUN npm install -g codex-cli to perform the installation. If your codebase lives in the container, copy it with COPY . /app and set WORKDIR /app. You can now invoke codex in any RUN or CMD instruction, letting you generate snippets or automate refactors as part of your CI pipeline. Remember to expose any required environment variables the CLI may need for authentication.

Related Articles

#Codex #Install #Web Development