Codex CLI Multi-File Operations & Large Codebase Guide (2026)
Codex CLI isn't limited to single files — it reads, modifies, and creates multiple files in a single task, coordinating cross-file refactors. But large codebases present challenges: bounded context windows, complex inter-file dependencies, and scope control. This guide covers proven strategies for using Codex CLI effectively on large projects.
1. How Codex CLI Handles Multiple Files
In both suggest mode (default) and auto-edit mode, Codex CLI actively reads relevant project files. You don't need to paste file contents into your prompt — Codex locates and reads the necessary files based on your description. Three core mechanisms drive this capability:
- Active indexing: At the start of a task, Codex scans the working directory (respecting
.codexignorerules) to build a file index. - On-demand reads: During task execution, Codex reads full file contents as needed, rather than loading everything upfront.
- Isolated context: Each task (each
codexcommand invocation) has its own isolated context. State does not carry over between tasks. Use AGENTS.md or explicit prompt context to pass information across sessions.
Examples: Operating on Multiple Files in a Single Task
# Method 1: List files explicitly
codex "Refactor the following modules, extracting duplicate error handling logic
into a shared function:
- src/api/users.ts
- src/api/products.ts
- src/api/orders.ts
Place the extracted function in src/utils/errorHandler.ts"
# Method 2: Describe scope
codex "Convert all class components under src/components/ to function components,
keeping props interfaces unchanged"
# Method 3: Describe by feature
codex "Extract all user auth code (login, register, token refresh) from src/app.ts,
create a standalone src/modules/auth/ directory with
router.ts, controller.ts, and service.ts"
You can also use the --context flag to manually pin specific files into the context, ensuring critical files are always included:
# Force-include specific files as context
codex "Refactor src/api/users.ts to match the code style in src/api/products.ts" \
--context src/api/products.ts \
--context src/types/global.d.ts
For large cross-module refactors, providing a clear input-output mapping in your prompt is the most effective approach: explicitly state which files are sources to read from and which are targets to modify or create. This dramatically reduces guesswork and misapplied edits.
2. Context Window Management
The context window is the total amount of text a model can process in a single operation. For Codex CLI, it directly determines the maximum amount of code that can be handled in one task. Understanding context window sizes across models helps you design realistic task-splitting strategies.
| Model | Context Window | Approx. Code Volume | Best For |
|---|---|---|---|
| o4-mini (default) | 128K tokens | ~90,000 lines | Most projects |
| GPT-4.1 | 1M tokens | ~700,000 lines | Very large codebases |
| o4-mini-high | 128K tokens | ~90,000 lines | Tasks requiring deeper reasoning |
Strategies for Optimizing Context Usage
- Focus on relevant files: Name specific files in your prompt rather than letting Codex scan the entire codebase
- Use .codexignore to exclude irrelevant content (see next section)
- Break large tasks into smaller steps: Focus on one module per task
- Provide architecture summaries, not full code: Describe project structure in AGENTS.md so Codex understands the big picture without reading every file
When a Task Exceeds the Context Window
# Wrong: refactor the entire large codebase at once
codex "Refactor the entire src/ directory to standardize error handling" # likely to exceed context
# Right: work module by module
codex "Refactor only the 3 files in src/api/ (users.ts, products.ts, orders.ts)
to standardize error handling"
codex "Now refactor the same pattern in src/services/"
codex "Finally refactor the related code in src/utils/"
Another common mistake is pasting large blocks of code directly into the prompt. Let Codex read files directly instead — copying code into the prompt consumes tokens and actually reduces the amount of code that can be processed.
3. .codexignore — Controlling Access Scope
The .codexignore file uses the exact same syntax as .gitignore. Place it in your project root to tell Codex CLI which files and directories to skip during scanning. Proper .codexignore configuration can significantly reduce the number of files Codex processes, improving both response speed and output quality.
# Create .codexignore (same syntax as .gitignore)
cat > .codexignore << 'EOF'
# Dependencies and build artifacts (no AI access needed)
node_modules/
.next/
dist/
build/
coverage/
.cache/
# Large data files
*.sql
*.csv
*.parquet
data/
# Binary files
*.jpg
*.jpeg
*.png
*.gif
*.ico
*.pdf
*.docx
*.xlsx
*.zip
*.tar.gz
# Sensitive configuration
.env
.env.local
.env.production
secrets/
*.key
*.pem
# Logs and temp files
*.log
tmp/
temp/
EOF
.codexignore to git version control (do not add it to .gitignore). This way your entire team shares a consistent Codex access-scope configuration, ensuring uniform behavior across all developers.
Verifying Which Files Codex Can Access
# Check how many TypeScript files remain after exclusions
find . -not -path './node_modules/*' -not -path './.next/*' -name '*.ts' | wc -l
# More comprehensive check for all JS/TS files
find . \( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' \) \
-not -path './node_modules/*' \
-not -path './dist/*' \
-not -path './build/*' | wc -l
For monorepos, you can place independent .codexignore files in subdirectories for finer-grained control. Subdirectory rules stack on top of root-level rules, giving you per-package access control.
4. AGENTS.md for Large Projects
For large codebases, AGENTS.md is absolutely critical. It lets Codex understand project architecture, key conventions, and operating rules without reading every file. A well-written AGENTS.md can reduce the context needed per task by more than 60%.
# Large Monorepo — AGENTS.md
## Project Architecture
This is a Turborepo monorepo with the following packages:
- apps/web: Next.js 15 frontend (React 19 + Tailwind)
- apps/api: Fastify backend (Node.js 20 + TypeScript)
- packages/ui: Shared UI component library
- packages/db: Database schema (Drizzle ORM + PostgreSQL)
- packages/shared: Shared utilities and types
## Key Conventions
- All packages use pnpm workspaces
- Cross-package imports use @repo/ prefix (e.g. @repo/ui, @repo/db)
- Each package has its own tsconfig.json extending the root tsconfig.base.json
- DB types are generated from packages/db/schema.ts — do not define them manually
## Modification Rules
- After editing packages/db/schema.ts, remind me to run drizzle-kit generate
- When editing packages/ui components, maintain backward compatibility
(other apps depend on these components)
- apps/api env vars are documented in apps/api/.env.example — no hardcoding
## Testing Requirements
- apps/web: vitest + @testing-library/react
- apps/api: vitest + supertest
- packages/*: vitest
- All new features must include test files
Per-Subdirectory AGENTS.md
In a monorepo, each app or package can have its own AGENTS.md with more specific constraints. Codex automatically merges AGENTS.md files from the root directory through to the current working path.
# apps/api/AGENTS.md — only affects API module operations
cat > apps/api/AGENTS.md << 'EOF'
# API Module — Additional Constraints
## Routing Standards
- All routes are versioned: /api/v1/
- Response shape: { data, meta, error }
- Pagination params: page, pageSize, total
## Database Operations
- No raw SQL — use Drizzle ORM exclusively
- Wrap multi-step mutations in db.transaction()
- Query timeout: 5 seconds
EOF
5. Monorepo Support (Turborepo / Nx / pnpm workspaces)
Codex CLI works with monorepo structures out of the box — no special configuration required. Here are four practical workflow examples covering the most common monorepo tasks:
Example 1: Cross-Package Refactoring
codex "Merge the duplicate User type definitions in apps/web and apps/api
into packages/shared/types.ts, then update all import paths
in both apps to use @repo/shared"
Example 2: Batch Dependency Updates
codex exec "Scan all package.json files under packages/, identify shared dependencies
(like zod, dayjs) that are on different versions, pin them all to the latest
stable version, and update pnpm-lock.yaml"
Example 3: Creating a New Package
codex "Create a new @repo/logger package under packages/:
- Built on pino
- Supports structured logging
- Unified log level configuration
- Replace existing console.log usage in apps/api
Follow the same directory structure as packages/shared"
Example 4: Syncing API Types (Backend to Frontend)
codex "Extract all request and response types from the routes in apps/api/src/routes/,
generate packages/shared/api-types.ts,
and update all API call sites in apps/web to use the new types"
For Turborepo projects, Codex CLI can understand the task dependency pipeline in turbo.json and factor in build order when suggesting changes. Documenting your Turbo pipeline configuration in AGENTS.md further improves Codex's understanding of the build topology.
nx.json and each library's tags in AGENTS.md. This helps Codex respect module boundaries and enforce dependency constraints when suggesting changes.
6. Incremental Refactoring Strategy
For large legacy codebases, incremental refactoring is the only sustainable path forward. The following four-step workflow has been validated across dozens of real-world projects.
Why You Can't Refactor a Large Codebase in One Shot
- A single task may exceed the context window, leading to omissions and errors
- Massive change scopes make thorough code review practically impossible
- When tests fail, pinpointing the cause becomes exponentially harder
- Merge conflict risk is high, especially in collaborative team environments
- The psychological weight of giant PRs often leads to abandonment mid-way
The Recommended Incremental Refactoring Workflow
Step 1 — Build a map (record in AGENTS.md):
codex "Analyze the src/ directory structure and generate a module dependency graph
(ASCII format) for AGENTS.md, along with a refactoring priority rating
(high/medium/low) for each module. Prioritize core modules that are
depended on by many others."
Step 2 — Start at leaf nodes (modules with fewest dependencies):
codex "Refactor src/utils/date.ts (no other modules depend on it):
- Replace hand-rolled date logic with date-fns
- Add full TypeScript type annotations
- Generate src/utils/date.test.ts with unit tests"
Step 3 — Update AGENTS.md to record progress:
codex "In AGENTS.md under the 'Refactoring Progress' section, mark
src/utils/date.ts as complete, and document the new date-fns APIs used
so that subsequent modules follow the same style"
Step 4 — Move inward (tackle modules that depend on already-refactored ones):
codex "Refactor src/services/user.ts (which depends on the refactored date.ts):
- Use the new date-fns APIs from date.ts
- Standardize error handling (see the error handling spec in AGENTS.md)"
Progress Tracking Template (Maintain in AGENTS.md)
## Refactoring Progress (2026-05-29)
✅ src/utils/date.ts — date-fns migration complete
✅ src/utils/string.ts — cleanup complete
🔄 src/services/user.ts — in progress
⬜ src/services/order.ts — pending
⬜ src/api/routes/ — pending
7. Real-World: Refactoring a 50K-Line TypeScript Codebase
The following is a complete walkthrough of migrating a 50,000-line TypeScript codebase from CommonJS to ESM, covering assessment, config updates, phased migration, and final verification.
# Phase 1: Assess the scope of impact
codex "Analyze all uses of require() and module.exports in src/,
generate a migration checklist: which files, how many lines,
dependency relationships, and risk assessment"
# Phase 2: Update config files only (don't touch source code yet)
codex "Update package.json (add type: 'module'), tsconfig.json
(module: 'ESNext'), and jest.config.js (ESM support) —
leave all source files untouched for now"
# Phase 3: Migrate utility functions first (leaf nodes)
codex "Convert all files under src/utils/ from CommonJS to ESM:
require → import, module.exports → export
Do not change any business logic; treat each file independently"
# Phase 3 verification
npx tsc --noEmit && npm test -- --testPathPattern=utils
# Phase 4: Migrate by module (repeat Phase 3 pattern)
codex "Migrate all files in src/services/ (depends on the migrated utils/)"
npm test -- --testPathPattern=services
codex "Migrate all files in src/api/"
npm test -- --testPathPattern=api
codex "Migrate src/app.ts and all entry point files"
# Phase 5: Full verification
codex exec "Run tsc --noEmit and npm test, collect all errors,
and generate a prioritized fix checklist"
The key lesson from this case study is: config first, code second. Update all build tooling to support ESM before touching a single source file. Run tests after each phase to catch regressions early rather than discovering a mountain of errors at the end.
./utils/date.js not ./utils/date). Have Codex fix import paths in the same step as each file's migration, rather than deferring this to a final cleanup pass that may miss dozens of occurrences.
8. FAQ
Can Codex CLI modify multiple files in one task?
Yes. Codex CLI reads, edits, and creates multiple files in a single task. List specific file paths in your prompt or describe the scope (e.g., "refactor all TypeScript files under src/") and Codex handles all involved files automatically. In suggest mode, Codex first shows you the complete list of files it plans to touch — you review and confirm before any changes are applied, making multi-file operations safe and auditable.
Does Codex CLI work on large codebases (100K+ lines)?
Yes, with the right strategy. For large codebases:
- Use
.codexignoreto excludenode_modulesand irrelevant directories, reducing scan scope - Split large tasks into module-focused steps, keeping each task under 500 lines of change
- Describe architecture in AGENTS.md so you don't have to re-explain context each time
- Target specific modules rather than the whole project in each prompt
For codebases exceeding 100K lines, consider switching to GPT-4.1's 1M token context (codex --model gpt-4.1).
What is Codex CLI's context window size?
The default model o4-mini supports a 128K token context window (roughly 90,000 lines of code). GPT-4.1 supports up to 1M tokens (roughly 700,000 lines). For most small to medium projects, 128K is more than sufficient. Even with a large context window, using .codexignore and decomposing complex refactors into smaller tasks produces higher-quality, more focused output.
How do I incrementally refactor a large legacy codebase?
Refactor module by module, starting from leaf nodes — modules with the fewest dependencies (typically utility functions). Verify tests pass after each module, then update AGENTS.md to record progress and document the patterns used. Move inward to modules that depend on already-refactored ones, and repeat. Never attempt to refactor the entire codebase in a single task — it's practically unreviable and substantially increases the risk of merge conflicts, cascading test failures, and difficult-to-trace regressions.