Skip to content

Migrating from Claude Code: Same Map, Different Tool, Still Find Your Way Home

📚 Series Navigation: The previous article "31 Advanced Tips and Speedup" talked about how to make the entire workflow run faster, more economically, and with less rework. This article takes a different angle—specifically written for you who are transitioning from Claude Code: out of the mental models you've used for over six months, which ones can be imported directly, which ones need renaming, and what new features are unique to Codex. The next article "33 Key Windows Considerations" will cover specific pitfalls on Windows.

Let me recount a real conversation. Last month, a friend who had been using Claude Code installed Codex, and immediately came up with a barrage of questions:

Him: "Where is Codex's CLAUDE.md? Why isn't it reading the one in my project root?" Me: "Codex doesn't recognize the name CLAUDE.md; it reads AGENTS.md, and you can pretty much copy the contents over as-is." Him: "What about the allow / deny permission rules in my settings.json?" Me: "You'll have to change those too—Codex uses ~/.codex/config.toml in TOML format. Its permission mindset is based on 'sandbox + approval' rather than allowedTools." Him: "What about running scripts with claude -p? And are slash commands like /compact and /clear still around?" Me: "claude -p maps to codex exec, and most of the slash commands are present with basically the same names. Simply put, 90% of your muscle memory works out of the box."

Hearing this, he sighed in relief—it turned out he wasn't learning a new tool from scratch; it was just the same map with different place names. This article aligns what he asked, and what he didn't have time to ask, all at once: which concepts map 1-to-1, which differences will cause trouble if copied blindly, and finally, walks you through rewriting a real CLAUDE.md into AGENTS.md manually.

After reading this article, you will get:

  • Peace of mind: 90% of your Claude Code mental models translate directly to Codex, making migration costs lower than you think
  • A complete comparison table of "Claude Code Concepts → Codex Counterparts," explaining key differences point-by-point
  • The pitfalls of copying settings blindly for the project manual, configuration files, and permission models where names are similar but behaviors differ
  • Things from Claude Code that do not exist or work differently in Codex, so you don't make assumptions
  • A hands-on process you can follow to migrate CLAUDE.md to AGENTS.md

⚠️ All references below to specific commands, config keys, and default behaviors are based on the official Codex documentation. Things like model names and version numbers vary across releases and are subject to whatever is shown on your local /model panel and in codex --help—don't memorize the names. Both tools are iterating rapidly; this comparison table explains "how concepts map" and is not a word-for-word guarantee.


01 First, Peace of Mind: 90% of Your Mental Models Carry Over

Let's make one thing absolutely clear to ease any anxiety: when migrating from Claude Code to Codex, you are not learning a new tool from scratch; you are just using the same underlying logic under a different shell.

Why are we so confident? Because at their core, they are the same type of tool—both are AI programming CLIs running in the terminal, execution of an "agentic loop," and both directly read and write your actual codebase. You saw these three points repeatedly in the Claude Code section, and not a single word changes for Codex.

Analogy: Switching from one Android brand to another. It's not like rebuilding everything from scratch when moving from Android to Apple—your muscle memory for dialing, messaging, installing apps, and swiping back is all there. Only the icons moved, the settings menu layout changed, and a few apps have different names. You don't need to re-learn "how to use a phone"; you just need to spend ten minutes finding out "where this device puts things." That is exactly the relation between Codex and Claude Code.

Specifically, what can be moved directly? When I switched from Claude Code to Codex, I never got stuck on the following:

  • The "Think → Act → Observe" agentic loop: You describe the requirement, it plans, modifies, and reviews the outcome. The flow is identical.
  • The habit of "reading first and approving the plan before execution": For unfamiliar projects, read first, outline a solution, and only make changes after approval. This applies to both.
  • The concept of "writing project rules into a file loaded automatically on every run": Only the filename and loading details differ (elaborated in the next section).
  • Slash commands as the "session console": Switching models, clearing context, and checking status all start with a /.

I the first time I officially used Codex was to migrate a FastAPI project from Claude Code last year. I practically navigated by blind habit—checking config with /status, switching models with /model, and asking it for a plan before editing—and 80% of my operations worked directly. The other 20% came down to filename and permission settings, which I resolved in ten minutes by checking the docs. That feeling of familiarity was much stronger than I had anticipated.

💡 Summary: Codex and Claude Code are the same type of tool (Terminal CLI + agentic loop + read/write actual codebase). 90% of your mental models translate directly; you only need to re-learn "where things are and what they are called."


02 A Master Comparison Table: Old Names → New Names

This section is the skeleton of the article—mapping every core concept from the Claude Code section to its name and location in Codex. Take a look at the table first for a high-level view, then we'll break down the lines with the biggest differences.

Claude CodeCodexRelationOne-line Difference
Project Manual CLAUDE.mdAGENTS.mdName changeSame concept, different discovery chain / override rules (see 03)
Configuration File ~/.claude/settings.json (JSON)~/.codex/config.toml (TOML)Format changeJSON -> TOML, entirely different keys and structure (see 04)
Permission Mode + allow/ask/deny rulesSandbox sandbox + approval approvalMindset changeFrom "whitelisting by tool" to "isolation + ask on exit" (see 05)
Headless Mode claude -pNon-interactive command codex execName changeBoth run and exit without entering interactive interface
CLAUDE.md Layering (User / Project / Subdirectory)AGENTS.md Layering (Global / Project hierarchy)MatchSame concept, Codex adds AGENTS.override.md
External Tool MCPMCPAlmost universalSame protocol, different config syntax
SubagentsSubagentsMatchPresent in both, different config paths
SkillsSkillsMatchPresent in both, slight directory structure variations
Slash Commands (/model, /compact...)Slash Commands (/model, /compact...)Mostly identicalCommand names are mostly identical, with a few exceptions (see 06)
Auto Memory (enabled by default)Memories / ChronicleEquivalent but different behaviorCodex memories are disabled by default, region-restricted, and asynchronously generated
Models Opus / Sonnet / HaikuGPT-5.x seriesModel changeFlagship gpt-5.5, lightweight gpt-5.4-mini, etc.

You don't need to memorize this table. Just remember one general rule:

Anything at the "concept" level (project manual, permissions, memory, subagents, skills, MCP) is present in both; migration is simply "renaming + adapting syntax." What will trip you up are those that "have similar names but behave differently"—namely the project manual, configuration files, and permission models. The next three sections target these three.

As for model mapping, to put it briefly: if you chose models in Claude Code as "Opus for heavy lifting, Sonnet for daily work, Haiku for trivial tasks," you can map this to Codex as "gpt-5.5 for heavy lifting, gpt-5.4-mini for trivial tasks." The selection logic (matching compute power to task difficulty) is identical; see "30 How to Choose Models" for details. Note that you should not treat gpt-5.4 as the flagship—the flagship is gpt-5.5, and gpt-5.4-mini is its lightweight version.

💡 Summary: Concepts map almost 1-to-1, and migration is mostly "renaming + adapting syntax." The real pitfalls lie in three areas with similar names but different behaviors: the project manual, configuration files, and permission models. Let's break them down.


03 Project Manual: CLAUDE.mdAGENTS.md

This is the first issue you will encounter when migrating, and my friend's very first question: Codex does not read CLAUDE.md. It ignores the one in your project root because it only recognizes the filename AGENTS.md.

The good news is: you can copy the contents almost as-is. Project overview, tech stack, common commands, coding conventions, and off-limits lists—these five categories share the same format and purpose on both sides. The guidelines you learned in Claude Code [18]—"write facts to remember for each round, delete anything that code can verify itself"—remain true here for AGENTS.md without changing a single word.

Analogy: Rewriting a hand-over document after changing companies. When you switch jobs, most of the core info in the previous "Project Spec" (tech stack, how to run tests, pitfalls to avoid) can be copied straight into the new company's template. However, the new company's archiving directory structure and naming conventions are different, and you must follow them. AGENTS.md represents this "copyable content, different archiving rules" scenario.

DimensionClaude Code (CLAUDE.md)Codex (AGENTS.md)
User-level location~/.claude/CLAUDE.md~/.codex/AGENTS.md
Project-level location./CLAUDE.md or ./.claude/CLAUDE.md./AGENTS.md (Project root)
Subdirectory levelCLAUDE.md in any subdirectory, loaded when readLoaded directory-by-directory from Git root to current, picking one per directory
Temporary overrideLocal variant CLAUDE.local.md (not in git)AGENTS.override.md (skips the same-level AGENTS.md)
Size limitBy lines (recommended < 200)By bytes (default 32 KiB combined, project_doc_max_bytes)

Three differences you must remember:

First, the temporary override mechanism is different. Claude Code uses CLAUDE.local.md for local preferences that only you see and aren't committed to git. Codex uses AGENTS.override.md—on the layer it exists, the same-level AGENTS.md is skipped entirely. These two are not the same: the former is for "appending personal content," while the latter is "use me on this layer, ignore the other one." See [11] for details.

Second, the size limit changes from "counting lines" to "counting bytes." Claude Code advises keeping CLAUDE.md under 200 lines; Codex has a hard limit—anything exceeding the default 32 KiB after merging gets truncated or entirely blocked. I learned this the hard way when migrating my FastAPI project: the original CLAUDE.md was bloated, and I didn't pay attention initially. I later found that instructions in a subdirectory weren't taking effect, only to find the merged volume had hit the limit. So trim down the file before migrating, deleting anything Codex can figure out just by reading the code.

Third, the discovery chain is "concatenation" rather than "override." The global file and project file both apply, and in case of conflict, the one closer to the current directory takes priority. This aligns with Claude Code's hierarchical loading, but Codex's merge order (root-to-leaf concatenation, closer directories appended later and thus having higher priority) is more explicit, as explained in [11].

💡 Summary: The contents of CLAUDE.md can be moved almost as-is to AGENTS.md, but there are three key differences: filenames, local override mechanisms (CLAUDE.local.mdAGENTS.override.md), and size limits (lines → bytes). Remember to trim the file before migrating.


04 Configuration File: settings.json (JSON) → config.toml (TOML)

The second pitfall: you cannot copy your configuration from ~/.claude/settings.json directly to Codex. The two use entirely different formats.

  • Claude Code: ~/.claude/settings.json, in JSON format; permissions, environment variables, hooks, and default models are all packed into this single file.
  • Codex: ~/.codex/config.toml, in TOML format; controls for models, sandbox, approvals, MCP, and more are configured here.

Analogy: Metric vs. Imperial wiring diagrams. The intent (which wire goes to which switch) is the same, but the units and notation system are different. You cannot hand an Imperial diagram to a Metric construction crew—you must convert and redraw it. Moving from JSON to TOML is this kind of "re-authoring with the same intent" task.

What You Want to ConfigureClaude Code (settings.json, JSON)Codex (config.toml, TOML)
Default model"model": "claude-..."model = "gpt-5.5"
Permissions / Safety"permissions": { "deny": [...] }sandbox_mode = "..." + approval_policy = "..."
Nested structureCurly braces { } + commasSection headers [section] + equals sign
String quotesDouble quotes requiredDouble quotes

A minimal comparison. Setting the default model in Claude Code (JSON):

json
{
  "model": "claude-sonnet-4"
}

Setting the default model + reasoning effort in Codex (TOML):

toml
# ~/.codex/config.toml
model = "gpt-5.5"
model_reasoning_effort = "medium"

Note a few TOML conventions that are easy to get wrong when transitioning from JSON: key-value pairs use = instead of :; do not wrap objects in curly braces, use section headers like [section]; do not append commas at the end of lines. When I first switched, I reflexively added commas to the end of every line in config.toml (due to JSON muscle memory), and Codex threw config parsing errors immediately. This is the most common mistake when moving from JSON to TOML, and I'm sharing it so you don't repeat it.

The complete breakdown of all switches in config.toml is in "18 config.toml Configuration in Detail". For now, you only need to align on this: don't try to "translate" the entire settings.json; instead, refer to the key table in [18] and re-configure the specific keys you actually use. Most people only ever customize three to five lines for the model, sandbox, and approvals.

💡 Summary: settings.json (JSON) → config.toml (TOML) is a format rewrite, not a copy-paste job. TOML uses =, [section] headers, and no trailing commas—keep JSON comma habits away. Just re-configure the keys you actually need using [18].


05 Permission Model: Permission Mode → Sandbox + Approval

This is the area with the greatest conceptual shift during migration, and the one most worth spending time to reconstruct. If you try to copy Claude Code's "whitelist-based" approach over, you will get lost.

Claude Code's permission model relies on two core concepts:

  • Permission mode: Six levels, from default (ask on every step) to bypassPermissions (allow everything), toggled via Shift+Tab.
  • Rule whitelist: Specifying allow / ask / deny rules in settings.json to fine-control rights by tool or command (e.g., denying rm -rf).

Codex doesn't use this system. It separates "how much can it modify" and "does it ask you" into two independent dials:

  • Sandbox: Controls "how much can it modify"—read-only, workspace-write, and danger-full-access.
  • Approval: Controls "does it ask you"—untrusted, on-request, and never.

Analogy: From "item-by-item expense approval" to "setting budgets + reporting only when over budget." Claude Code is like the old-school expense approval—you specify beforehand for every single item (tool/command) whether it's allowed and whether it asks. Codex is like a modern budget system—it first sets a "budget boundary" (sandbox), and you can spend freely within it without interruptions (approvals don't trigger). Only when you exceed this boundary does it pause for approval. The former manages by "items," the latter by "boundaries." This is a fundamental shift in mindset.

Desired EffectHow to Set in Claude CodeHow to Set in Codex
Read-only, do not modify filesdefault mode / read-onlySandbox read-only
Modify in project, ask for external changesacceptEdits typeSandbox workspace-write + Approval on-request (Daily golden combo)
Full auto, don't ask anythingbypassPermissionsSandbox danger-full-access + Approval never (--yolo is more absolute: bypasses sandbox entirely)
Block specific dangerous commandWrite rules under permissions.denyUnder rules (experimental), use prefix_rule() to match command prefix with decision = "forbidden" to block
Toggle levelToggle with Shift+Tab/permissions in session or passing -s / -a at startup

A few concepts you must align on when migrating:

First, "not asking" does not equal "granting permissions." In Claude Code, settings get progressively looser as you move down; in Codex, these two dials are independent. You can absolutely set "read-only + never ask" (read-only + never), meaning "feel free to read, but don't interrupt me at all." never simply suppresses the approval prompts; it does not grant write permissions.

Second, the default level is linked to "whether there is Git." Codex intelligently picks settings on startup: directories managed by Git get workspace-write + on-request (Auto level), while directories without Git default to read-only. This is a thoughtful safety net that Claude Code lacks—avoid opening full access inside non-Git temp directories (as I mentioned in [15], doing so made my spine tingle).

Third, under workspace-write, network access is disabled by default, and .git is read-only protected. These defaults are counter-intuitive and are easy to trip over if you copy over Claude Code habits. If you need network access, you must explicitly enable network_access.

The complete details of permissions are in "15 Permissions, Sandbox, and Approval". When migrating, focus on establishing the new mindset of "two independent dials" instead of shoehorning it into the old "whitelist-based" framework.

💡 Summary: Claude Code's "permission mode + allow/deny whitelist" maps to Codex's "sandbox (what it can touch) + approval (when it asks)—two independent dials." Remember: "not asking != granting access," defaults depend on Git presence, and network access is off by default under workspace-write—copying these blindly will cause trouble.


06 Interaction Habits: Similarities and Differences in Slash Commands and Session Management

The good news is back: once inside a session, most of your muscle memory works out of the box. Slash commands share a very high overlap, and the common ones use the exact same names.

ActionClaude CodeCodexIdentical Name?
Switch model/model/model
Compress context/compact/compact
Clear screen & start new session/clear/clear
Check status / config/status (or /config)/statusBasically equivalent
Generate project manual/init/init✅ (one generates CLAUDE.md, the other AGENTS.md)
View changes diff/diff/diff
Have it review changes/review/review
Toggle permission tightnessShift+Tab/permissions❌ Different entry

The differences lie mainly in two aspects:

First, toggling permissions uses a different entry point. Claude Code uses the Shift+Tab shortcut to cycle through permission modes; Codex uses the slash command /permissions to show a selector menu. The functionality is equivalent, but the feel is different—switching from a shortcut key to a menu select.

Second, /clear and /new are more granular in Codex. In Codex, /clear means "clear screen + start new session," whereas /new means "start new session without clearing screen." Claude Code relies mainly on /clear to switch tasks (and older sessions can be retrieved via /resume). A minor detail, but worth knowing.

My own experience in the first week after migrating: I barely had to look up commands—switching models with /model, checking status with /status, and compressing context with /compact were all second nature. The only time I stumbled was trying to adjust permissions: I instinctively pressed Shift+Tab and got no response, before remembering Codex uses /permissions. The complete slash command reference is in "12 Slash Commands and Keybindings", but you can easily proceed with your old habits and check only when stuck.

💡 Summary: Slash commands share high overlap (/model, /compact, /clear, /diff, /review are identical). Use them based on habit and look up when stuck. The main difference is permission toggle: Shift+Tab in Claude Code, and /permissions in Codex.


07 Don't Assume: Things That Do Not Exist or Differ in Codex

The biggest risk during migration is not lack of familiarity, but assuming it behaves the same as Claude Code when it doesn't. This section calls out a few common assumptions.

First, the memory system defaults are opposite. In Claude Code, auto-memory is enabled by default, segmented by Git repositories, and loaded at startup. Codex's Memories are disabled by default, region-restricted, generated asynchronously in the background, and use a different storage path and control mechanism. When my friend first switched, he assumed "it remembers as soon as I say it"—only to use the wrong package manager next time. He brought along Claude Code's "memory by default" assumption. For hard rules that must apply every time, write them into the project manual (AGENTS.md) on both sides instead of relying on memory. See [19] for details.

Second, Codex has features that do not exist in Claude Code. Don't assume it's just "renamed"; some are entirely new additions:

  • AGENTS.override.md: An override file for temporarily stamping rules on that layer, which lacks a direct counterpart in Claude Code ([11]).
  • Chronicle: The ability to feed memory using screen contents. Currently marked as a "research preview," it must be manually enabled, is region-restricted, and is unique to Codex ([19]).
  • Git-based default levels: Automatically chooses sandbox settings at startup depending on the presence of a Git repo ([15]).

Third, conversely, some Claude Code elements take a different form in Codex. For instance, Claude Code's CLAUDE.local.md local variant is replaced by AGENTS.override.md in Codex but with different semantics. The precise command whitelist in Claude Code is mapped to experimental rules in Codex (written in Starlark, not a JSON array).

Your Potential AssumptionThe Reality
❌ Codex reads CLAUDE.md too✅ It only reads AGENTS.md (unless you configure project_doc_fallback_filenames)
❌ Memory is enabled by default and remembers everything instantly✅ Memories are disabled by default, generated asynchronously, and region-restricted
❌ Just copy settings.json over✅ It must be rewritten as config.toml in TOML
❌ Permissions are whitelisted by tool✅ Managed via two dials: Sandbox + Approval
Shift+Tab toggles permissions✅ Codex uses the /permissions command

💡 Summary: The biggest risk in migration is assuming things work the same—memory is disabled by default (not enabled), Codex adds unique features like AGENTS.override.md / Chronicle / Git-based defaults, and permissions are managed by dials rather than a whitelist. Review the checklist above before starting.


08 Hands-on: Rewriting a CLAUDE.md to AGENTS.md

Just reading without practicing won't stick. Let's walk through migrating a real-world style CLAUDE.md to AGENTS.md and verifying that Codex reads it. Follow along; it takes just five minutes.

A quick note on platform differences: the commands mkdir and git init below work directly in Mac / Linux. On Windows, we recommend using Git Bash or WSL, or creating files manually via File Explorer. The path ~ refers to the user's home directory (mapped to C:\Users\<username>\ on Windows).

Step 1: Prepare the CLAUDE.md to be migrated.

Create a toy project and add a typical CLAUDE.md (assuming you copied it from a Claude Code project):

bash
mkdir migrate-demo && cd migrate-demo
git init

Create a new CLAUDE.md in the project root, pasting the following (intentionally including a line of useless fluff to demonstrate slimming it down):

md
# migrate-demo Project Manual

This is an order management backend based on FastAPI. This project was initiated by the Order Team in 2023.
It initially used Flask and was later migrated to FastAPI for asynchronous performance. The technical selection went through three rounds of reviews... (a long background story)

## Tech Stack

- Python 3.11 / PostgreSQL / pytest

## Common Commands

- `pytest` —— Run tests
- `ruff check .` —— Run linting

## Coding Conventions

- All functions must have type annotations
- Strings must consistently use double quotes

## Off-Limits

- Do not modify existing migration files in migrations/
- Ask me before adding new production dependencies

Expected result: CLAUDE.md appears in the project root. Notice that the background story is useless for Codex when writing code, making it the perfect candidate to delete during migration.

Step 2: Rewrite as AGENTS.md.

Create a new AGENTS.md, copy the content over, and trim away that project background (keep almost everything else):

md
# migrate-demo — FastAPI-based Order Management Backend

## Tech Stack

- Python 3.11 / PostgreSQL / pytest

## Common Commands

- `pytest` —— Run tests
- `ruff check .` —— Run linting

## Coding Conventions

- All functions must have type annotations
- Strings must consistently use double quotes

## Off-Limits

- Do not modify existing migration files in migrations/
- Ask me before adding new production dependencies

Expected result: AGENTS.md appears in the project root, noticeably shorter than the original CLAUDE.md. Everything trimmed was background information Codex could verify itself or didn't need in the first place. This is a living example of "reusing content while streamlining."

Step 3: Ask Codex to repeat the instructions it read to verify migration success.

Run inside the project directory (we add --ask-for-approval never to avoid approval prompts and keep the output clean—this is the standard official way to verify if AGENTS.md is loaded, so use it with confidence):

bash
codex --ask-for-approval never "Summarize the current instructions."

Expected result: Codex will echo the rules you just wrote—tech stack, pytest / ruff commands, type annotations, double quotes, no migrations edits, and no new dependencies. Once it repeats them, it proves that AGENTS.md has indeed been loaded into the context for this round, meaning migration succeeded.

Step 4 (Optional): Clean up the old CLAUDE.md.

Once migrated and verified, keeping the old CLAUDE.md has no impact (Codex ignores it), but it might confuse team members. Whether you delete it is up to you—this is a file-modifying action, so handle it manually rather than letting the tool do it. If you want Codex to recognize CLAUDE.md as well (for side-by-side coexistence during the transition), add the following to ~/.codex/config.toml:

toml
# ~/.codex/config.toml
project_doc_fallback_filenames = ["CLAUDE.md"]

With this added, Codex's lookup sequence in each directory becomes AGENTS.override.mdAGENTS.mdCLAUDE.md, picking the first non-empty file that exists. If you want the old CLAUDE.md to be read during transition, this is the easiest way (restart Codex for changes to take effect).

💡 Summary: Migration = copying CLAUDE.md content into AGENTS.md + trimming backgrounds. Verify via "Summarize the current instructions." If you want the old CLAUDE.md to be recognized during transition, add a single project_doc_fallback_filenames config line.


Summary

This article has walked through the migration from Claude Code to Codex:

DimensionKey Conclusion
General Verdict90% of mental models carry over. You only need to learn "where things are and what they are called."
Project ManualCLAUDE.mdAGENTS.md. Contents can be copied, but local override mechanisms and size limits (lines → bytes) differ.
Config Filesettings.json (JSON) → config.toml (TOML). Rewrite in the new format, and avoid JSON trailing commas.
Permission ModelPermission modes + whitelists → two independent dials: Sandbox + Approval. "Not asking != granting rights."
Interaction HabitsSlash commands share identical names. The main difference is permission toggle (Shift+Tab/permissions).
Don't AssumeMemory is disabled by default, and Codex adds unique features like AGENTS.override.md / Chronicle.

You should now be able to: cleanly migrate a CLAUDE.md file to AGENTS.md; know which lines in config.toml should replace settings.json; swap out the old "permission mode + whitelist" framework for the new "sandbox + approval" model; and sidestep the pitfalls of assuming Codex behaves exactly like Claude Code. Simply put—your hard-earned Claude Code experience was not in vain; you've just switched tools, but you can still find your way home.


The next article "33 Key Windows Considerations"—I repeatedly advised Windows users to run commands "in Git Bash or WSL." Why is that? What specific pitfalls exist for running Codex on Windows regarding sandboxes, paths, and terminals? A quick question to ponder: how does Codex control sandboxing on an OS that lacks native Linux isolation capabilities? The next article will explain Windows-specific details thoroughly.