Codex · EN · Part 1
Ch 03 Installation And Configuration
03-ch-03-Installation-and-Configuration.md
第3章 Installation and Configuration
Installation Methods
Codex CLI offers multiple installation paths, each suited to different environments and workflows. The right choice depends on your platform, update preferences, and whether you need the absolute latest features.
npm installation
The simplest installation method uses npm, which auto-updates and works across platforms:
npm install -g @openai/codex
This command installs the latest release and registers the codex binary in your global path. The npm package wraps the platform-specific binary, so you get the right executable for your system automatically.
🤿 深入底层:The npm package lives in
codex-cli/at the repository root. It's a thin wrapper that downloads the appropriate pre-built binary for your platform duringnpm install—the actual Rust compilation happens upstream during the release process, not on your machine.
Homebrew installation
On macOS and Linux, Homebrew provides another managed installation path:
brew install --cask codex
Homebrew handles updates alongside your other cask applications. Use brew upgrade --cask codex to get the latest version.
Pre-built binaries
For maximum control or air-gapped environments, download binaries directly from GitHub Releases:
# Check the latest release at:
# https://github.com/openai/codex/releases/latest
# macOS (Apple Silicon)
curl -L https://github.com/openai/codex/releases/download/vX.X.X/codex-aarch64-apple-darwin.tar.gz | tar xz
mv codex-aarch64-apple-darwin codex
chmod +x codex
sudo mv codex /usr/local/bin/
# Linux (x86_64)
curl -L https://github.com/openai/codex/releases/download/vX.X.X/codex-x86_64-unknown-linux-musl.tar.gz | tar xz
mv codex-x86_64-unknown-linux-musl codex
chmod +x codex
sudo mv codex /usr/local/bin/
Each release contains executables for multiple platforms. Rename the downloaded file to simply codex after extraction—otherwise you'll be typing codex-x86_64-unknown-linux-musl every time you want to run a command.
Building from source
Building from source requires the Rust toolchain and is primarily for contributors:
# Install Rust if needed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
# Clone and build
git clone https://github.com/openai/codex.git
cd codex/codex-rs
cargo build --release
# The binary is at target/release/codex
⚠️ 避坑指南:First-time Rust compilation can take 10-30 minutes depending on your hardware. The workspace has 90+ crates with complex dependencies. Use
cargo build(without--release) during development for faster iteration—release builds optimize everything and take significantly longer.
Troubleshooting common issues
Problem: codex: command not found
Solution: Your PATH isn't configured correctly. Verify the installation location:
# For npm installations
which codex # Should show something like /usr/local/bin/codex
# If not found, check npm's binary location
npm config get prefix # Add bin/ subdirectory to your PATH
Problem: Permission denied when running codex
Solution: The binary lacks execute permissions:
chmod +x /path/to/codex
Problem: "Unable to load libstdc++" or similar system library errors
Solution: On older Linux distributions, you may need updated C++ standard libraries:
# Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y libstdc++6
# CentOS/RHEL
sudo yum update libstdc++
Authentication: API Keys vs OAuth
Before Codex can process code, it needs credentials. Two authentication paths are available, each with different trade-offs.
API key authentication
The simplest method uses an OpenAI API key directly:
codex login
# Select: "Sign in with API key"
# Paste your key when prompted
The API key is stored in ~/.codex/auth.json:
{
"auth_mode": "api_key",
"OPENAI_API_KEY": "sk-proj-..."
}
You can also set the key via environment variable (no login required):
export OPENAI_API_KEY="sk-proj-..."
codex "hello world"
API keys work with any OpenAI API plan and are straightforward to revoke. However, they don't include ChatGPT subscription benefits like higher rate limits or access to certain models.
ChatGPT OAuth authentication
For ChatGPT Plus, Pro, Team, Edu, or Enterprise subscribers, OAuth integration provides seamless authentication:
codex login
# Select: "Sign in with ChatGPT"
# Browser opens to ChatGPT OAuth flow
# Complete authentication in browser
The stored credentials include an access token and refresh token:
{
"auth_mode": "oauth",
"tokens": {
"access_token": "...",
"refresh_token": "...",
"expires_at": "2026-04-05T10:30:00Z"
}
}
☕ 茶水间时间:OAuth tokens expire periodically. Codex handles refresh automatically using the stored refresh token, but if you see "refresh token expired" errors, you'll need to run
codex loginagain to establish a fresh session.
Credential storage
Authentication credentials live at ~/.codex/auth.json by default, but the storage backend is configurable:
# In ~/.codex/config.toml
[auth]
store_mode = "file" # Default: stores in ~/.codex/auth.json
# store_mode = "keyring" # Use system keyring (fails if unavailable)
# store_mode = "auto" # Try keyring, fall back to file
# store_mode = "ephemeral" # Memory-only for current process
On Unix systems, file-based storage uses mode 0o600 (read/write for owner only). Keyring storage uses the platform's secure credential manager (Keychain on macOS, Windows Credential Manager on Windows, secret-service on Linux).
Security implications
Each authentication method has different security considerations:
| Method | Credential Exposure | Revocation | Rate Limits |
|---|---|---|---|
| API Key | Visible in auth.json and shell history | Regenerate at platform.openai.com | Standard API limits |
| ChatGPT OAuth | Token stored securely, no manual key handling | Revoke via ChatGPT account settings | ChatGPT plan limits (typically higher) |
Key security practices:
- Never commit
auth.jsonto version control - Add
~/.codex/to your.gitignoreglobally - Use environment variables for API keys in CI/CD environments
- Rotate API keys periodically if using key-based auth
Switching methods
You can switch between authentication methods at any time:
# Currently using API key, want to switch to OAuth
codex login # Select "Sign in with ChatGPT"
# Previous auth.json is overwritten with OAuth tokens
# Currently using OAuth, want to test with an API key
codex logout # Clears existing credentials
codex login # Select "Sign in with API key"
The codex logout command removes stored credentials entirely. No confirmation is prompted, so be certain before running it.
Configuration System Deep Dive
Codex uses a three-layer configuration system that merges settings from multiple sources, with well-defined precedence rules.
Three-layer configuration system
Configuration flows from three sources, in order of precedence (highest last):
- System defaults: Built into the binary
- User config:
~/.codex/config.toml - Project config:
.codex/config.tomlin your project directory - Session flags: CLI arguments like
-c model=gpt-5
Rendering diagram...
The merge algorithm is recursive: later layers override specific keys rather than replacing entire sections. If your user config sets [tui] options and your project config sets [sandbox] options, both take effect simultaneously.
Configuration precedence
Understanding precedence is crucial when settings conflict. Consider this scenario:
User config (~/.codex/config.toml):
[model]
provider = "openai"
model = "gpt-5"
reasoning_effort = "medium"
[tui]
theme = "dark"
Project config (.codex/config.toml):
[model]
model = "gpt-5-codex-max" # Overrides user's model choice
[tui]
theme = "light" # Overrides user's theme preference
CLI flag:
codex -c model=gpt-5-codex -c reasoning_effort=high
Effective configuration:
model = "gpt-5-codex"(from CLI flag, highest precedence)reasoning_effort = "high"(from CLI flag)provider = "openai"(from user config, no override)theme = "light"(from project config)
The rule: more specific wins. CLI flags beat project config, which beats user config, which beats defaults.
Common configuration patterns
Here's a minimal but functional configuration covering common needs:
# ~/.codex/config.toml
# Model selection
[model]
provider = "openai"
model = "gpt-5" # Default model
reasoning_effort = "medium" # For reasoning models
# Sandbox mode - start conservative
[sandbox]
mode = "read-only" # See docs for workspace-write options
# TUI preferences
[tui]
theme = "auto" # auto/dark/light, or custom theme name
notifications = true # Desktop notifications when unfocused
alternate_screen = "auto" # Disable in Zellij, enable elsewhere
animations = true # Welcome screen effects, spinners
# Memory system (advanced)
[memories]
generate_memories = true # Extract context from past threads
use_memories = true # Inject relevant memories into new threads
max_rollout_age_days = 30 # Only use threads from last 30 days
# History tracking
[history]
persistence = "save-all" # Write all history to disk
# max_bytes = 10485760 # Optional: cap history file size
Project-specific configurations typically override only what's necessary:
# .codex/config.toml (project-specific)
[model]
model = "gpt-5-codex-max" # Use more capable model for this project
[sandbox]
mode = "workspace-write" # Allow file writes in this project
writable_roots = ["."] # Only write to project directory
[memories]
generate_memories = false # Disable memory extraction for this project
CLI flag overrides
CLI flags provide temporary overrides without editing configuration files:
# Override model for a single session
codex -c model=gpt-5-codex-max "refactor this function"
# Combine multiple overrides
codex -c model=gpt-5 -c reasoning_effort=high -c sandbox.mode=danger-full-access
# Override nested config keys with dot notation
codex -c tui.theme=light -c sandbox.mode=workspace-write
The -c flag accepts dotted paths that mirror the TOML structure. Use this for one-off experiments or when you don't want to commit configuration changes to disk.
⚠️ 避坑指南:CLI overrides apply only to the current session. They don't modify your config files, but they also don't persist for future runs. For repeated needs, add them to your project's
.codex/config.tomlinstead.
Running Your First Real Tasks
With Codex installed and configured, let's walk through three practical scenarios that demonstrate different aspects of the system.
Refactoring scenario
Start with a function that needs improvement:
// calculator.rs
fn calculate_price(base: f64, tax: f64, discount: f64) -> f64 {
let with_tax = base * (1.0 + tax / 100.0);
let with_discount = with_tax * (1.0 - discount / 100.0);
with_discount
}
Run Codex with a refactoring request:
codex "Refactor calculate_price to use a Builder pattern for better readability"
What happens behind the scenes:
- Codex reads the current file contents
- Sends the code plus your request to the configured model
- The model proposes edits via the
apply_patchtool - You're prompted to approve the changes (or set approvals to auto-accept)
- The patch is applied and the file is updated
Expected output:
I'll refactor the calculate_price function to use a Builder pattern.
Let me create a new implementation...
[Proposed changes to calculator.rs]
+ pub struct PriceBuilder {
+ base: f64,
+ tax_rate: f64,
+ discount_rate: f64,
+ }
+
+ impl PriceBuilder {
+ pub fn new(base: f64) -> Self {
+ Self { base, tax_rate: 0.0, discount_rate: 0.0 }
+ }
+
+ pub fn tax(mut self, percent: f64) -> Self {
+ self.tax_rate = percent;
+ self
+ }
+
+ pub fn discount(mut self, percent: f64) -> Self {
+ self.discount_rate = percent;
+ self
+ }
+
+ pub fn calculate(self) -> f64 {
+ let with_tax = self.base * (1.0 + self.tax_rate / 100.0);
+ let with_discount = with_tax * (1.0 - self.discount_rate / 100.0);
+ with_discount
+ }
+ }
+
+ fn calculate_price(base: f64, tax: f64, discount: f64) -> f64 {
+ PriceBuilder::new(base)
+ .tax(tax)
+ .discount(discount)
+ .calculate()
+ }
Approve these changes? [y/n]
Test generation scenario
Codex can generate tests for existing code. Given a function:
// lib.rs
pub fn fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
Run:
codex "Generate comprehensive unit tests for the fibonacci function, including edge cases"
Behind the scenes:
- Codex locates the function in your codebase
- Analyzes the signature and implementation
- Creates a new test file or adds to existing tests
- Uses proper Rust testing conventions
Expected output:
I'll generate comprehensive tests for the fibonacci function.
[New file: lib_tests.rs]
+ #[cfg(test)]
+ mod tests {
+ use super::*;
+
+ #[test]
+ fn test_fibonacci_zero() {
+ assert_eq!(fibonacci(0), 0);
+ }
+
+ #[test]
+ fn test_fibonacci_one() {
+ assert_eq!(fibonacci(1), 1);
+ }
+
+ #[test]
+ fn test_fibonacci_small_values() {
+ assert_eq!(fibonacci(2), 1);
+ assert_eq!(fibonacci(5), 5);
+ assert_eq!(fibonacci(10), 55);
+ }
+
+ #[test]
+ #[should_panic] # Known limitation: recursive implementation is slow
+ fn test_fibonacci_large_value() {
+ fibonacci(50); # This will take a long time
+ }
+ }
Approve test file creation? [y/n]
Debugging scenario
When tests fail, Codex can help diagnose the issue:
cargo test
# Output: test test_fibonacci_small_values ... FAILED
# assert_eq!(fibonacci(10), 55) got 89 instead
Run Codex with the error context:
codex "The fibonacci test is failing. fibonacci(10) returns 89 but should return 55. Debug what's wrong."
Behind the scenes:
- Codex reads the test output you provide
- Examines the fibonacci implementation
- Identifies the off-by-one error or logic mistake
- Proposes a fix
Expected output:
Let me analyze the fibonacci function and the failing test.
[Reading lib.rs]
[Reading lib_tests.rs]
I found the issue! The test expectation is incorrect. The fibonacci sequence
is: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...
So fibonacci(10) should actually be 55, but let me trace through the code:
fibonacci(10) = fibonacci(9) + fibonacci(8)
= 34 + 21 = 55 ✓
The code is correct, but the test has the wrong expectation. The standard
fibonacci sequence gives:
Position: 0 1 2 3 4 5 6 7 8 9 10
Value: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
[Proposed change to lib_tests.rs]
- assert_eq!(fibonacci(10), 55);
+ assert_eq!(fibonacci(10), 55); # This is correct!
Wait, let me recheck. The test expects 55 and the code returns 89.
Let me trace more carefully...
Actually, there may be an indexing issue. Let me add debug output:
Understanding output
Codex's output includes several key elements:
- Tool calls: When Codex uses tools like
apply_patchorshell, you'll see structured output showing what's happening - Streaming responses: Model responses stream in token-by-token, so you see progress in real-time
- Approval prompts: For file edits and command execution, you'll be asked to confirm unless you've configured automatic approvals
- Status indicators: The TUI shows context usage, model information, and current operation status
The JSONL log file at ~/.codex/history.jsonl records every session for later reference, which is useful for reviewing what changed when something breaks.
With Codex installed, authenticated, and configured, you've completed the setup phase. The three scenarios above demonstrate the core interaction loop: request, tool use, approval, and result. Part II dives into the core systems that power everything—the agent orchestration, tool execution, and state management that make this loop possible.