Splitting Work Between Claude Code and Codex on One Mac: Claude Designs, Codex Implements
This is a continuation of my "Claude Code environment" series, following How I split Claude Code's memory into four layers. This time I want to write about making Claude Code and Codex CLI divide the work between them inside a single Mac.
The trigger was simple: when I run my main session on a lightweight model, it feels wasteful to burn tokens on the long typing of implementation. Design and review benefit from how smart the model is, but the process of just churning out predetermined implementation is something I'd rather offload to a separate process. So I settled on delegating implementation to Codex while keeping design, research, and review on the Claude side.
Dividing the work: separate the brain from the hands
I've spelled out the division of labor in CLAUDE.md. The gist is this:
| Process | Owner | Reason |
|---|---|---|
| Design, codebase research, planning | Claude (main) | Requires understanding context and judging trade-offs |
| Implementation, refactoring, test generation | Codex | Offload the boilerplate, large-scale, and repetitive work to the typing side |
| Code review | Both | Add a second engine's eyes to raise quality |
The key point is not to delegate everything. When an implementation is highly difficult, or involves heavy design judgment, the main session that holds the context can write it directly, faster and more accurately. Delegation is strictly limited to the "mass-produce the predetermined stuff" process.
The axis is separating the processes that need the model's intelligence (design, review) from those that need volume more than intelligence (boilerplate implementation). It's not "since I have two AIs, parallelism makes it faster" - it's "choose which work to seat in the expensive chair."
How to invoke it: fire it off headlessly and safely
Codex is installed as a CLI (codex-cli 0.135.0). I delegate via non-interactive headless execution.
# Implementation / task delegation (you can reference files with @file)
timeout 600 codex exec --skip-git-repo-check "<request>" </dev/null
# Code review (run against the current repo)
codex exec review </dev/null
There are three small but effective points:
- Close stdin with
</dev/null. If you don't, Codex waits for interactive input and freezes, staying stuck all the way to the timeout for nothing. - Wrap it in
timeout. Headless AI processes occasionally never finish. Setting things up so the OS can reap them keeps stuck processes from piling up. --skip-git-repo-check. Needed when running in a directory outside a git repo. Without it, the repo check rejects the run.
The PATH trap
Codex is installed under nvm. Claude's Bash during an interactive session has already loaded the nvm default, so codex just works - but from a bare zsh or via cron, you can get command not found. In that case, call it by its full path:
/Users/<you>/.nvm/versions/node/v24.13.0/bin/codex exec ...
When you run it unattended from launchd or cron, nvm isn't in the minimal PATH, so you're guaranteed to trip on this. Specifying the full path is the reliable fix.
The delegation flow
The actual operational flow looks like this:
- Main (Claude): receives the requirements, researches the codebase, and lays out the design and plan
- Judge the scale: if it's boilerplate, large-scale, or repetitive, delegate; if it's a hard spot, implement it directly in main
- Delegate (Codex): throw the concrete task to
codex execand have it implement - Review (Codex): once implementation is done, run
codex exec reviewfor code review - When main gets stuck: hand it off to Codex
Splitting steps 3 and 4 across different engines is quietly effective. When the same model reviews as "the person who wrote it," the review tends to go soft, but by having Codex write and Codex review - or having Claude review - you can separate the author from the reviewer.
Don't break the handoff: passing state through files
For long delegations, I pass tasks, handoffs, and state through files. Conversation context is volatile, so writing the state to disk makes resuming and verifying easier. When I run things isolated in a worktree, I write the branch and worktree path into a status file.
# Status
- State: running
- Updated: 2026-06-17T...
- Branch: feat/...
- Worktree: `/path/to/worktree`
This is the same philosophy as the four-layer memory piece. Keep the canonical copy of state outside the volatile conversation. Whether it's collaboration or long-term memory, the principle that works turned out to be the same.
Pitfalls I hit
- Forgetting
</dev/nulland Codex freezing while waiting for input โ always close stdin codex: command not foundfrom cron/launchd โ it's under nvm, so the full path is mandatory- Running outside a git repo gets rejected โ
--skip-git-repo-check - Delegating everything and losing context โ write the hard spots directly in main; limit delegation to boilerplate
- Soft reviews when author = reviewer โ split implementation and review across different engines
Summary
- Within one machine, split design and review to Claude, boilerplate implementation to Codex
- Delegate via non-interactive execution:
codex exec --skip-git-repo-check "..." </dev/nullwrapped intimeout - Don't delegate everything. Write the hard spots directly in main
- Split implementation and review across different engines to raise quality
- Write state to files. Keep the canonical copy outside the volatile conversation
Next time I'll write about a hook that mechanically stops secrets from leaking right before that push - Stopping API keys and accidental pushes with a pre-push guard.
Lily (@bokuwalily) - indie developer. I build automation infrastructure with Claude Code while mass-producing iOS apps and web services.
- The apps I've built are collected in my portfolio ๐ฑ
- I share new releases and behind-the-scenes development on X @bokuwalily ๐
- OSS: github.com/bokuwalily ๐
- I wrote about how I used this setup to run an "environment" instead of "work" and got back to ยฅ1.2M/month, free on note
Your โค๏ธ and shares keep me going!
Comments
No comments yet. Start the discussion.