The complete guide to Codex

By

Updated

Tagged: AI

Learn Codex from your first project to tested, reviewed changes: desktop app, CLI, instructions, permissions, skills, plugins and practical coding workflows.

Codex is OpenAI’s coding agent. It can read your project, edit files, and run commands. In this tutorial we’ll use it to fix a reading-time calculator, test the result, and review the changes before committing them.

We’ll start in the desktop app, where the chat, terminal, browser, and diff share a window. You can follow the same exercise in the CLI if you prefer the terminal or work over SSH.

Codex can inspect your Git history and project instructions too. When you connect other tools, it can use those during the task.

The desktop app is where I use Codex most. Later we’ll look at the CLI and the configuration they share.

The screenshots were taken in September 2026. Some controls have moved since then; the official Codex documentation has the current interface details.

If you already have Codex installed, jump to the reading-time exercise. It includes the starting files, a change to request, a reference solution, and a recovery exercise. For terminal setup, go to the CLI section.

What Codex does in your project

Codex works directly in your project. You can ask it to find a bug, change the code, and run the tests, instead of copying code between a chat and your editor.

A task can span several files. In the desktop app, it can also open a web app in the browser to check the result.

The agent works in a loop. It reads the result of each tool call before choosing what to do next:

A Codex coding taskCodex inspects the project, edits it and checks the result, repeating when verification finds a problem before the human reviews it.NoYesDescribe the resultRead relevant filesEdit and runcommandsChecks pass?Human review

I treat it like a developer who just joined the project. I explain what I want, point it at the useful context, and say how I will decide the work is done.

If this workflow is new to you, my AI fundamentals guide explains agents, tools, context, permissions, and verification from the beginning.

What you need

You need a project folder, a ChatGPT account or an OpenAI API key, and Git installed. The exercise also needs a recent version of Node.js. Git gives us a history of changes and a way to return to a known version.

Codex is included in every ChatGPT plan, the Free one too. Checked in October 2026, the individual plans are Free at $0, Go at $8 a month, Plus at $20, and Pro at $100, $200 or $500 a month. Business and Enterprise plans include it as well.

Free and Go give you Codex in the desktop app with GPT-6 Luna, and that access is still rolling out. Plus adds Codex in the CLI, the IDE extension, on the web and on iOS, the cloud features like code review, and the GPT-6.1 Sol model. Among the individual plans, only Pro at $500 includes GPT-6 Astra Ultrafast, a mode that generates tokens up to 8x faster than Astra at standard speed.

The plan gives you a usage allowance that Codex shares with ChatGPT Work, so a long agent session and your Work tasks draw from the same pool. How far it goes depends on the model, the size of the task, and whether it runs locally or in the cloud. The usage page in the app shows where you stand and when the limits reset. Check it every week or two until you know your pace.

You can also run Codex with an OpenAI API key. Usage is then billed at API rates instead of counting against a plan, but the cloud features that need a ChatGPT account, such as automatic GitHub code review, don’t work with a key. The authentication docs list the sign-in methods.

We’ll use a small JavaScript project that runs locally, with no database or deployment service to configure.

InterfaceWhere I would startWhat to check
Desktop appA local app with a browser flow to testCorrect project and permissions
CLIA terminal session or repeatable scriptCurrent directory and sign-in method
IDE extensionA task starting from an open fileWorkspace and attached selection
CloudWork delegated to a configured remote environmentSetup commands and required services

Start with the desktop app

Codex lives inside the ChatGPT desktop app, available on macOS, Windows, and Linux. In the app switcher, choose Codex. The other choice, ChatGPT, contains the Chat and Work views.

I’ll call it the Codex desktop app throughout this guide.

You can add local projects and run several chats. You can also inspect diffs, open files, use a terminal, preview web apps, install plugins, and create scheduled tasks without leaving the app.

Download it from openai.com/codex, sign in, and switch to Codex.

Downloading the Codex desktop app

Then add the folder you want to work on. Codex lists the Git repositories you used recently, but you can pick any folder from disk.

Selecting a project folder in the Codex desktop app

Once the app opens, you can start a chat or select one of your projects from the sidebar.

The Codex project screen in the desktop app

Before asking Codex to change anything, try a read-only question:

Explain what this project does, ELI5.

Check its answer before asking for edits. It should identify the project correctly and point to the relevant files.

I like the app because I can stay in one place from the first prompt to the final review. I can also leave a long task running, move to another chat, and return when Codex needs me.

Build a small project to learn the loop

Our reading-time calculator takes a string of text and returns the number of minutes needed to read it. Its source and tests fit in a few files, so we can read every change Codex makes.

We’ll start with working code and ask Codex to add one missing behavior.

Create a folder and the directories for the source and tests:

mkdir reading-time
cd reading-time
mkdir src test

Create package.json in that folder:

{
  "name": "reading-time",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "test": "node --test"
  }
}

We’ll use Node’s built-in test runner, so there are no dependencies to install.

Create src/reading-time.js:

export function readingTime(text, wordsPerMinute = 200) {
  const words = text.split(/\s+/).filter(Boolean).length
  return Math.max(1, Math.ceil(words / wordsPerMinute))
}

The function splits text at whitespace and rounds up the reading time. It returns at least one minute, even for empty text. We’ll keep that behavior while changing how it handles code blocks.

Now create test/reading-time.test.js:

import { test } from 'node:test'
import assert from 'node:assert/strict'
import { readingTime } from '../src/reading-time.js'

test('a short post takes one minute', () => {
  assert.equal(readingTime('Hello world'), 1)
})

test('four hundred words take two minutes', () => {
  assert.equal(readingTime('word '.repeat(400)), 2)
})

test('empty text keeps the one minute minimum', () => {
  assert.equal(readingTime(''), 1)
})

Run the tests yourself before introducing the agent:

npm test

Fix any failures before continuing. We need to know these tests pass before asking Codex to change the function.

Store the starting version in Git:

git init
git add package.json src test
git commit -m "Add reading time calculator"

If Git asks for an author name and email on your first commit, configure them using the Git setup lesson and retry the commit. Continue once the checkpoint exists.

Open this folder in Codex. In the desktop app, add it as a project. In the terminal, run codex from this directory.

The calculator currently counts fenced code blocks as prose. We want to exclude those blocks from the estimate.

Start with an explanation:

Explain how the reading-time calculator works and which tests cover it.
Don't edit files. Point out what happens to Markdown fenced code blocks.

Read the answer. Codex should identify the function and the test file. If it starts talking about a different project, fix the project selection before continuing.

Then give it the change:

Exclude Markdown fenced code blocks from the reading-time calculation.
Handle backtick and tilde fences, including an unclosed fence at the end.
Preserve the one-minute minimum and the wordsPerMinute parameter.
Inline code should still count as text.

Add focused tests and run npm test. Use no dependencies.
Keep the function's public API unchanged.

This request names the fence formats to support and the behavior to preserve. It also tells Codex how to check the change.

The model may choose a different implementation each time. Review the behavior rather than expecting it to produce one particular regular expression.

Check a reading-time changePreserve the original passing tests, add examples of fenced code, implement the missing behavior, then check the tests and diff.Run baseline testsDescribe excludedfencesAdd regressionexamplesImplement the changeRun all testsInspectimplementation anddiff

Check the test the agent added

A test with ten prose words and ten code words returns one minute with either implementation. It passes even when the bug is still there.

Use enough code to cross the reading-time boundary. For example, this case should stay at one minute even though the fenced section contains 800 words:

test('fenced code does not inflate reading time', () => {
  const markdown = ['A short introduction.', '```js', 'word '.repeat(800), '```'].join('\n')
  assert.equal(readingTime(markdown), 1)
})

Ask Codex to verify that this test fails against the original implementation and passes with the fix. That proves the test distinguishes the two behaviors.

Now look at what it considers a fence. Can it handle indentation? Does it close a tilde block with backticks by mistake? What happens when an opening fence has a language label?

For this exercise, check which Markdown cases the function handles. If you need full Markdown compatibility in a production feature, choose a parser or document the subset you support.

Refine the same task

Suppose the agent’s first version removes inline code too. Continue in the same chat:

The prompt said inline code should count as text. The implementation removes it.
Add a regression test that fails with this version, preserve inline code,
and rerun the tests. Keep the fenced-code behavior.

The correction points back to the inline-code requirement and asks for a test. Codex has a specific behavior to fix.

When you’re satisfied, inspect git diff or open the app’s review panel. You should see changes to the calculator and its tests. A new framework, a build pipeline, or an unrelated dependency would need an explanation.

Once the behavior matches the prompt and you’ve reviewed the tests and diff, commit the change.

A reference result to compare with

Try the agent exercise before reading this implementation. If you get stuck, replace src/reading-time.js with this complete reference and compare it with the diff Codex produced:

export function readingTime(text, wordsPerMinute = 200) {
  const prose = []
  let fence = null

  for (const line of text.split(/\r?\n/)) {
    if (fence) {
      const closing = new RegExp(`^ {0,3}${fence.character}{${fence.length},}\\s*$`)
      if (closing.test(line)) fence = null
      continue
    }

    const opening = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/)
    if (opening && !(opening[1][0] === '`' && opening[2].includes('`'))) {
      fence = { character: opening[1][0], length: opening[1].length }
      continue
    }

    prose.push(line)
  }

  const words = prose.join('\n').split(/\s+/).filter(Boolean).length
  return Math.max(1, Math.ceil(words / wordsPerMinute))
}

This recognizes top-level backtick and tilde fences with up to three leading spaces. A closing fence must use the same character and at least the opening length. An unclosed fence excludes the remaining lines. Inline code stays in the prose.

It is a small parser for this exercise. It doesn’t handle every Markdown container, such as fenced blocks nested inside blockquotes. Keep that boundary in mind before reusing it in a publishing system.

Keep the original tests, then append these cases to test/reading-time.test.js:

test('tilde fences do not inflate reading time', () => {
  const markdown = ['Intro.', '~~~js', 'word '.repeat(800), '~~~'].join('\n')
  assert.equal(readingTime(markdown), 1)
})

test('an unclosed fence excludes the remaining code', () => {
  const markdown = ['Intro.', '```js', 'word '.repeat(800)].join('\n')
  assert.equal(readingTime(markdown), 1)
})

test('a different fence character does not close the block', () => {
  const markdown = ['Intro.', '```js', '~~~', 'word '.repeat(800), '```'].join('\n')
  assert.equal(readingTime(markdown), 1)
})

test('inline code still counts as text', () => {
  assert.equal(readingTime('`word` '.repeat(400)), 2)
})

test('the custom reading speed still applies', () => {
  assert.equal(readingTime('word '.repeat(400), 100), 4)
})

Run npm test after adding these and the backtick regression test above. With Node.js, this reference passes all nine tests: the three starting tests, the backtick regression, and these five. A passing suite covers these cases, not every possible Markdown document.

Recover from an unwanted change

Before another task, commit the reading-time behavior you reviewed above. Run git status --short and check that the working tree is clean. This gives us a known version to return to.

For this exercise, make an unwanted edit yourself: change the minimum in src/reading-time.js from 1 to 0. Run npm test. The empty-text test should fail.

Stop any running Codex task before undoing its changes. Otherwise it can write another edit while you’re reviewing the first one.

Open the app’s diff panel, or inspect the two exercise files in the terminal:

git status --short
git diff -- src/reading-time.js test/reading-time.test.js
git diff --cached -- src/reading-time.js test/reading-time.test.js

The first diff shows unstaged changes. The second shows staged changes. In this exercise, only the minimum should have changed, and nothing should be staged.

If those files contain only the unwanted work from this attempt, restore their working copies from the last commit:

git restore --source=HEAD --worktree -- src/reading-time.js test/reading-time.test.js
npm test
git status --short

This replaces the working copies of those two tracked files. The tests should pass again. It leaves other paths and untracked files alone, and it does not unstage changes.

Don’t use that whole-file command when a file also contains edits you want to keep. Choose the unwanted hunks interactively instead:

git restore --patch --source=HEAD --worktree -- src/reading-time.js

Read each patch before answering. Split a hunk when Git offers that option, or quit and edit the file manually if the changes are mixed together. Inspect the staged diff separately; a working-tree restore does not remove what you already staged.

The app also provides revert controls in its review panel. Read the selected file or hunk before confirming. A new chat won’t undo files, and a Git restore won’t undo something an MCP tool changed in another service.

Recover a Codex edit without discarding other workStop the task and inspect staged and unstaged changes. Restore whole files only when all their edits are unwanted; otherwise select hunks, then rerun tests.YesNoStop the runningtaskInspect both GitdiffsOnly unwanted edits?Restore named filesSelect hunks or editmanuallyRun tests andinspect status

Carry useful findings into a fresh chat

If the approach was wrong but the investigation was useful, save the findings before starting over. Ask Codex to record the failing input, relevant files, and the checks still needed. Review that file too.

For example, save this as RECOVERY.md in the project:

# Reading-time task

Keep the one-minute minimum, including for empty text.
Exclude backtick and tilde fenced code blocks. Inline code still counts.
The source is src/reading-time.js; tests live in test/reading-time.test.js.
Run npm test. Check that regression tests fail against the original behavior.

Start a new chat in the same project and attach the file:

Read RECOVERY.md and inspect the current Git diff.
Explain the next small change before editing anything.
Preserve changes that were already present when this chat started.

For a change already committed, use a reviewed revert commit instead of pretending it is an uncommitted edit. My Git course covers that workflow and how to inspect the history first.

Understand the app interface

Your projects and chats are in the sidebar. You’ll also find plugins, scheduled tasks, and settings there.

Move the pointer over a project and click the new chat button.

Starting a new chat from a Codex project

Click the project name above the prompt to switch projects, add another one, or start a chat without a project.

Choosing a project for a new Codex chat

The conversation is in the center. Codex uses it to explain what it’s doing, ask questions, show command output, and report back when it’s done.

On the right you can open the project files, a terminal, the built-in browser, or the Git diff. I open and close these panels depending on what I’m doing.

At the bottom is the prompt panel. Besides writing your request, you can use it to:

  • attach a file or image
  • choose a model and reasoning level
  • choose the project, environment, and branch
  • change what Codex can do without asking

The prompt panel in the Codex desktop app

For a Git repository you also choose whether the chat works in your local checkout or in a separate worktree. We’ll look at that choice later.

Click the reasoning level to decide how much time Codex should spend thinking about the task.

Choosing a reasoning level from the Codex prompt panel

Click the model name when you want to use a different model.

Choosing a model from the Codex prompt panel

Type / to open the commands available in the current chat.

Opening slash commands in the Codex prompt panel

Some controls depend on the project and app version, so your screen may differ from these screenshots.

Organize projects and chats

A project connects Codex to a folder. Each chat holds one conversation and its work.

I keep the authentication fix in one chat, including the follow-up tests and corrections. An unrelated dependency update gets its own chat.

Rename chats you want to find later. I pin the important ones and archive the ones I’m done with. Archiving removes a chat from the active list without deleting its transcript.

Give Codex useful project instructions

Codex automatically reads files named AGENTS.md before it starts working.

Use AGENTS.md to explain how Codex should work on the project: which commands to run, which conventions to follow, and what to check before finishing.

You can ask Codex to create a starting file after it inspects the project. Then edit it, because the generated file is only a first draft.

A useful AGENTS.md might look like this:

# Project instructions

## Commands

- Run `npm run dev` to start the site.
- Run `npm test` after changing JavaScript files.
- Run `npm run build` before finishing.

## Code style

- Use plain JavaScript, not TypeScript.
- Use 2-space indentation.
- Do not add a dependency without asking first.

## Definition of done

- The requested behavior works.
- Existing tests still pass.
- New behavior has a test when practical.

Keep the file short and specific. Instead of asking for “good code”, list the commands, directories, constraints, and recurring mistakes Codex needs to know about.

You can put one AGENTS.md in the repository root and more specific files inside subdirectories. Instructions discovered closer to the current working directory take precedence. The official discovery rules explain the global file, root-to-working-directory chain, and overrides.

I wrote a separate guide about how AGENTS.md works, including global instructions, nested rules, overrides, and maintenance.

Decide what context belongs where

A common temptation is to paste the whole project into the first prompt. Codex can search files, so start with the outcome and the context it cannot discover by reading code.

For the reading-time calculator, the one-minute minimum is visible in the implementation. The reason for keeping it is a product decision. Saying that explicitly prevents the agent from “fixing” empty text to return zero while working on fences.

InformationWhere I would put itExample
Requirement for this changeCurrent promptInline code still counts
Project-wide working ruleAGENTS.mdRun npm test after a JavaScript change
Repeatable procedureA skillReview a release before tagging it
Current external dataPlugin or MCP toolRead the failed CI job
Decision needed in a future chatRepository documentationWhy the estimate has a one-minute minimum

Save decisions you will need in future chats in the repository. A new chat won’t necessarily have the conversation where you agreed on the one-minute minimum.

Choose a home for agent contextSequential questions place task requirements in the prompt, shared rules in AGENTS.md, procedures in a skill, live data behind MCP, and other durable context in project docs.YesNoYesNoYesNoYesNoTask-specific?PromptShared rule?AGENTS.mdWorkflow?SkillLive data?MCP toolDocs

Write a good prompt

Describe the behavior you want to change. Codex can read the project, but it needs you to explain what the result should be.

Include the details Codex cannot guess:

  • the result you want
  • the behavior that must not change
  • a useful file, error, screenshot, or Git commit when you have one
  • a check it can run when the work is done

This prompt is too vague:

Improve the settings page.

Give Codex the missing details:

On the settings page, the Save button stays enabled after a successful save.
Disable it until the form changes again.

The form is in src/components/SettingsForm.tsx.
Keep the existing API and visual design.
Add a test for the saved state, then run the settings form tests.

The file path gives Codex a starting point. The rest explains what to change and what to preserve.

Examples are more useful than adjectives. Instead of asking for a “robust” URL function, include a few inputs and the exact outputs you expect.

Point at real evidence when you have it. Paste the complete error instead of summarizing it. Attach a screenshot for a visual problem. Name a file if you know where the relevant code lives.

Let Codex inspect the project before you prescribe an implementation. Describe the result and constraints, especially when you’re unsure how the existing code works.

If you do not know which files matter, do not guess. Ask Codex to find them.

Find the code responsible for saving the settings form. Explain the current flow,
then propose the smallest change that keeps Save disabled after a successful save.
Do not implement it yet.

Pick a model and reasoning level

The composer lets you choose a model and its reasoning level.

Model names change, so there isn’t one model I can always recommend. Start with the default and switch when you have a reason.

Use lower reasoning for a clear, small change. Use higher reasoning for debugging, migrations, architectural work, or a task where several constraints interact.

A typo does not need the same reasoning as a database migration. Higher reasoning takes longer and uses more tokens.

Settings worth checking

Open Settings from the sidebar or the application menu.

Opening Codex settings from the sidebar

Before your first coding task, check the permission defaults and project settings.

Under General, check the default permissions. Codex normally recommends workspace write for a Git repository. An untrusted folder or a folder without version control can start read-only. Check the selected mode before sending a task.

General settings and permissions in Codex

Personalization holds your global instructions, which tell Codex how to communicate and work with you in every project.

Personalization settings in Codex

Git covers branch names, commits, and how work comes back into your checkout. The choice that matters most is whether pull requests use merge commits or squash commits. Pick what your team already does.

Using merge commits in Codex Git settings

Using squash commits in Codex Git settings

Worktrees sets where Codex creates its managed worktrees, $CODEX_HOME/worktrees by default, and how many it keeps around. Check the cleanup settings before relying on a worktree for long-running work. Pin or preserve work you still need.

Worktree settings in Codex

You’ll also find these settings:

  • Appearance: theme, colors, and fonts.
  • Keyboard shortcuts: change the keys used around the app.
  • Environments: setup scripts and quick actions for a project. A worktree can run them to install its dependencies.
  • Plugins: plugins, apps, MCP servers, and skills. We’ll come back to it.
  • Browser: the built-in browser and its browsing data.
  • Computer use: the desktop apps Codex may use.
  • Archived chats: restore a chat you archived.
  • Usage and billing: your plan, credits, and current limits.

The Codex interfaces share the same configuration layers. Personal defaults live in ~/.codex/config.toml. A project can keep shared settings in .codex/config.toml.

Make a small project configuration

For the reading-time project, we only need local edits, approval when more access is needed, and cached web search. Create the configuration directory from the project root:

mkdir -p .codex

Then save this as .codex/config.toml:

approval_policy = "on-request"
sandbox_mode = "workspace-write"
web_search = "cached"

This is the complete file for this exercise. If you already have one, edit the relevant values and keep the other settings. Don’t replace an existing configuration with this small example.

workspace-write limits local command writes to the workspace and other allowed roots. on-request lets Codex request approval for actions that need it. The web-search setting controls the search tool; it doesn’t give arbitrary shell commands network access.

Codex only loads project configuration after you trust the project. Review .codex/ before trusting a repository someone else sent you. Your organization can enforce requirements that this file cannot override.

A trusted project’s settings override your personal defaults, and command-line overrides can take precedence for one run. See configuration precedence.

Start a new CLI session, then inspect what took effect:

/debug-config
/status

/debug-config shows the configuration layers and enforced requirements. /status shows the session’s active settings. If a value differs from the file, inspect those layers before changing more settings.

An AGENTS.md sentence asking Codex to avoid deployment describes how it should work. Permissions and the sandbox determine which actions can run. Keep both consistent with the task.

Understand permissions and the sandbox

For local commands, the sandbox limits filesystem and network access. The approval policy decides when an action needs approval. Approval requests can go to you or a configured automatic reviewer. Browser access, Computer Use, and MCP tools have separate permission controls.

Workspace write lets Codex edit the project while restricting writes elsewhere. Some paths inside the project, including .git, remain protected and can require approval.

A package installation may need network access. Computer Use may ask for access to an app. Check what is being requested, especially when a command can affect production.

Read the command before approving it. Be especially careful with commands that delete files, rewrite Git history, rotate secrets, change a production database, or spend money.

Goals and scheduled tasks keep the same permissions. Running for longer does not give Codex more access.

Sandbox and approval are separate checksAn action must fit the sandbox or receive approved escalation; permission to run a command does not verify that the command is correct.YesNoYesNoAgent proposes anactionInside allowedboundary?Run under currentpolicyRequest more accessApproved?Use another approachor report blockerInspect result

Use Plan mode before a difficult change

Plan mode lets Codex inspect the project and propose an approach before editing files.

You can select Plan in the composer or type:

/plan

Here I selected Plan before asking Codex to check whether a project needed dependency updates:

Starting a task in Plan mode

When the plan is ready, Codex asks whether it should implement it.

A completed plan ready for implementation

Read it and correct any assumptions before approving implementation.

Ask for a plan when:

  • you are not sure about the implementation
  • the change crosses several parts of the project
  • the order matters
  • a wrong assumption would be expensive

I skip Plan mode for tiny edits. For a larger change, I want to catch a wrong decision while it’s still a plan.

Make the change

Once the plan looks right, tell Codex to implement it.

For example:

Implement the plan. Run the relevant tests and the production build.
Do not change files outside the areas listed in the plan.

Codex now reads the files, applies its patches, and runs the commands from the plan. You can move to another chat or continue your own work. The app sends a notification when Codex needs a decision or finishes.

A desktop notification from Codex when a plan is ready

You can also steer a running task. Send another message when you notice a missing constraint:

Keep the existing URL structure. Other sites link to these routes.

I do this often. I would rather add the constraint immediately than wait for the wrong change to finish.

Use Goal mode for long work

Plan mode works out how to approach one task. Goal mode keeps Codex working toward a result that may take much longer.

Click Goal in the composer to switch modes:

Selecting Goal mode in Codex

Then describe the result you want Codex to keep pursuing:

Migrate to the latest version of Astro and make sure the project follows best practices.

Writing a goal for Codex

Tell Codex what counts as finished, what it must preserve, and which checks to run.

You can pause, resume, edit, or clear a goal. It keeps the same sandbox and permission boundaries as a normal task.

I tested Goal mode by asking Codex to recreate PocketBase with two different stacks. It ran for over 24 hours and produced two impressive prototypes, but both still needed a lot of manual work.

My preferred workflow is still one feature at a time, followed by a review. I use a long-running goal when the destination is precise enough for Codex to know when it’s done.

Set a limit for an experiment

A long goal should have a small enough scope that you can decide whether it worked. For our calculator, you could ask:

Set a goal to finish fenced-code support in the reading-time project.
Preserve the one-minute minimum and the public function signature.
Finish when npm test passes, including a regression test that fails
against the original implementation. Then stop and summarize the diff for me.
Use a token budget of 200000. Do not commit or publish.

A budget only limits the goal if Codex stores it with the goal. If the goal doesn’t show a budget, the number in your prompt is just an instruction. The token budget also doesn’t cap what external tools or services cost, so keep an eye on /usage too.

Review every change

When Codex finishes, open the review panel. The green and red counters show how many lines changed. Click them to see the diff:

A completed Codex task ready for review

The Codex review panel showing a multi-file diff

The review menu lets you switch how the changes are displayed.

Choosing how to view a Codex review

I like the split view when I want to compare the old and new versions side by side.

Reviewing a change in the split diff view

Read the diff before you commit. Check that:

  • the change matches the request
  • unrelated files were left alone
  • errors and edge cases are handled
  • tests cover the important behavior
  • no secret or generated file slipped into Git

You can leave a comment on a specific line and ask Codex to address it:

Leaving feedback on a specific line in the Codex diff

I often ask for one final check after the tests pass:

Review the full diff for regressions, unnecessary complexity, and anything
that does not match the request. Fix real issues, then run the checks again.

Codex has a built-in version of this. Type /review in the composer and choose whether to review against a base branch or the uncommitted changes. A separate reviewer reads that diff and reports prioritized findings, without changing your working tree. In Settings > General > Code review you can make it run in a detached chat, so the review doesn’t fill up the chat that did the work.

Commit and push with Git

The desktop review panel can stage, revert, commit, push, and open a pull request.

Git actions in the Codex review panel

You can write the commit message yourself or let Codex propose one.

Writing a Git commit from the Codex review panel

For a personal project, I often work directly in my normal checkout and commit after reviewing the result. In a team, I would use a branch and open a pull request so CI and other people can review the change.

I run the checks before committing and read the diff myself.

From local change to published codeLocal edits become a reviewed commit, then a push; deployment happens only when the repository workflow or a separate deployment action runs.Local editsTests and behaviorchecksReview diffCommitPushRepository CI ordeployment workflow

A push can trigger a deployment if the repository is configured that way. Ask Codex to check the project workflow before treating push as a harmless backup step. The reading-time exercise has no deployment workflow; a connected production app may have one.

Browse the project files

The desktop app has a file panel for quickly opening files without switching to an editor.

Open the panel menu and choose Files.

Opening the panel menu in Codex

The file browser in the Codex desktop app

I use this while reviewing an explanation or comparing a changed file with its neighbors. For a long editing session, I still prefer a full editor.

You can also attach a file from the prompt panel. Attach one when you know it matters; let Codex search the repository when you don’t know where to start.

Use the integrated terminal

Every desktop chat has a terminal scoped to its project or worktree. Open the panel menu and choose Terminal.

The integrated terminal beside a Codex chat

Use it to start the development server, run Git commands, inspect logs, or try the result yourself.

When I want a separate terminal, I use the Open button at the top of the chat instead. It opens the project, or the worktree, in your editor or terminal app. Click the arrow next to it to pick one: VS Code, Cursor, Zed, Ghostty, iTerm2, Warp, and a few more. Mine defaults to Ghostty.

Opening the project in an external terminal or editor from Codex

Codex can read the current terminal output. If a build fails, you can ask:

Read the terminal output, find the first real error, and fix it.

For a web app with a dev script, start npm run dev, leave it open, and let the agent use the browser against the local URL. Our reading-time exercise has only a test script; it does not need a development server.

Test web apps in the built-in browser

The desktop app includes a browser. Open it from the panel menu or mention @Browser in your prompt.

A local site open in the Codex browser

The built-in browser has its own profile. Your open Chrome or Safari tabs, cookies, and logged-in sessions are not carried over. When a task needs your real browser with its logins, the browser extension connects Codex to Chrome, Edge, Brave, Opera, or Vivaldi. Set it up from Settings > Computer use and mention @Chrome in the prompt.

In a separate web project with a settings page, ask Codex to start the server and open the route:

Start the development server, open http://localhost:4321/settings in @Browser,
and verify the form at desktop and mobile widths.

You can turn on annotation mode, click an element, and describe the exact change you want:

Annotating a local web page in the Codex browser

This is one of my favorite parts of the app. Instead of describing “the text block on the right under the second heading”, I click it and write “make this font larger”.

The selection goes to Codex with your prompt. After the change, ask it to check that element again in the running page.

Codex verifying the change in the built-in browser

Codex can also inspect the DOM, console, network requests, and performance data when browser Developer mode is enabled.

I use the browser again after the last change. In the prompt I name the page, the state I want to test, and anything that must stay unchanged.

Give Codex images and screenshots

Codex can inspect screenshots, mockups, diagrams, and error messages.

In the desktop app, attach an image and explain what matters:

Compare this screenshot with the current checkout page. Fix spacing and
typography only. Do not change the form behavior. Verify with @Browser.

Tell Codex what to inspect in the image and what result you want.

Codex can also generate and edit images. Ask in natural language, or invoke the image generation skill with $imagegen when it is installed.

GPT-Image-2.6

On 4 November 2026 OpenAI brought GPT-Image-2.6 to Codex and the API. The two models are Image-2.6 Flare and Sunburst. They generate images 50% faster than before. At medium or high quality, Sunburst keeps details more consistent from one edit to the next.

Codex image edits now happen directly in the overlay. OpenAI’s follow-up shows that. They used to open a side panel.

Use Computer Use for desktop apps

The built-in browser handles web apps. Computer Use lets Codex work with graphical interfaces outside the browser. Cursor has its own version; I wrote how to use Cursor Computer Use.

In supported regions, Computer Use can operate macOS and Windows apps, reproduce a desktop-only bug, change settings, or work across several applications.

Computer Use is a plugin. Open Plugins > Computer Use, install it, and turn on its server and skill toggles. On macOS, grant Screen Recording and Accessibility when the system asks for them.

Installing the Computer Use plugin in Codex

Settings > Computer use is where you review the apps Codex may use, and where you remove an app you allowed for future tasks.

Computer Use settings in Codex

Mention @Computer or the app name in the prompt:

Open the app with Computer Use, reproduce the onboarding bug, and fix the
smallest code path that causes it. Run the same UI flow after each change.

Computer Use can affect apps outside the project folder. I keep these tasks narrow and read the permission prompts. On Windows, it uses foreground input, so you can’t keep using the same desktop while it works.

If a service has a dedicated plugin or MCP server, prefer that structured connection. Use Computer Use when the task truly depends on what is visible in the interface. Codex’s plugin is the built-in path. When you want the same kind of desktop control from any agent that can run a shell, agent-desktop reads the accessibility tree and acts on refs.

Connect external tools with MCP

The context Codex needs is not always in the repository. It might be in GitHub, Slack, Notion, Google Drive, a database, or an internal service.

MCP stands for Model Context Protocol. It gives Codex structured tools for working with those systems.

An MCP server defines what Codex can read or do. It can expose tools such as:

  • list open pull requests
  • read an issue
  • query deployment logs
  • create a task
  • fetch a document

In the desktop app, open Settings > Plugins > MCPs to see what is connected and add a server.

The Plugins settings page in Codex, with tabs for plugins, apps, MCPs, and skills

Connect a service when you have a task for it, such as reading a failed deployment’s logs. Here are the MCP servers I actually use and how they work in Codex.

Connect the OpenAI documentation server

We can use a real connection to check how Codex discovers the skill we’re about to create. OpenAI’s Docs MCP server searches and retrieves official documentation. It is read-only and doesn’t call the OpenAI API on your behalf.

This public server needs no API key or OAuth sign-in. From your terminal, add it:

codex mcp add openaiDeveloperDocs --url https://developers.openai.com/mcp
codex mcp list

The CLI command saves a user-level connection in ~/.codex/config.toml, so it can appear in other projects too. Keep any existing entries in that file.

Alternatively, to share this connection only through the reading-time project, add this table to the project’s .codex/config.toml instead of running the add command:

[mcp_servers.openaiDeveloperDocs]
url = "https://developers.openai.com/mcp"

Choose one scope for the exercise so you know where the connection came from. A project entry loads only for a trusted project, and another computer still needs network access to the server.

Restart the client or connection as needed, then run /mcp. Look for openaiDeveloperDocs and its documentation search and fetch tools. The configured-server list alone doesn’t prove that the tools connected successfully.

Ask for a narrow lookup:

Use the openaiDeveloperDocs MCP server to find the current Codex skill-discovery docs.
Fetch the relevant page. Tell me where this repository's SKILL.md should live,
then compare that rule with .agents/skills/check-reading-time/SKILL.md if it exists.
Include the official source link. Do not change files.

You should see a search tool call followed by a page fetch, with an answer pointing to the official skill documentation. Verify the answer against the returned page. If the skill file doesn’t exist yet, the agent should say that rather than claim to have inspected it.

If it answers from memory without a tool call, repeat the request with the server name. If tools are missing, run /mcp verbose for diagnostics and check the URL, configuration scope, and network policy. A configured entry with a failed connection needs troubleshooting before you trust its result.

This server never asks you to sign in. If you see an authentication prompt, recheck the URL instead of pasting credentials. Other MCP servers often do need OAuth, so follow their own setup instructions.

To undo the user-level setup:

codex mcp remove openaiDeveloperDocs
codex mcp list

If you used the project configuration, remove only its [mcp_servers.openaiDeveloperDocs] table and restart the connection. Inspect /mcp again to confirm which tools remain. Another configured scope can still supply a server with the same name.

The MCP configuration guide explains server scopes, diagnostics, and authentication.

Reuse workflows with skills

A skill teaches Codex how to perform one repeatable job. It’s a folder with a SKILL.md file and, when needed, scripts, references, templates, or assets.

For example, a skill could explain how to:

  • check a deployment before a release
  • review a database migration
  • prepare release notes
  • diagnose a failed deployment

A skill tells Codex how to do the work. An MCP server gives it live data and actions.

Skills and MCP have different jobsA skill provides the release procedure; Codex uses a connected service to inspect CI, then produces release notes for review.ProcedureCI resultsRelease skillCodexGitHub MCPDraft release notesHuman review beforepublication

For example, a release skill can require passing CI and a reviewed changelog. A GitHub connection lets Codex retrieve the real CI result. Having the skill alone doesn’t grant access to GitHub, and connecting GitHub doesn’t tell the agent your release procedure.

Browse skills in the desktop app. A good skill has a narrow job, clear trigger phrases, and an output you can verify.

Browsing the skills available in Codex

If you keep pasting the same instructions into prompts, turn them into a skill.

Skills add up quickly, and several end up doing nearly the same job. I built Skill Cabinet to see every skill on my Mac, which agents load it, and to merge the ones that read alike.

How to write an Agent Skill walks through building, testing, and packaging one.

Build a skill for the reading-time project

We keep checking the same things after each change: the one-minute minimum, fenced blocks, and whether the tests catch the missing behavior. Put that review procedure in a project skill.

Create its folder from the project root:

mkdir -p .agents/skills/check-reading-time

Save this complete file as .agents/skills/check-reading-time/SKILL.md:

---
name: check-reading-time
description: Review changes to this project's reading-time calculator and its tests. Use after changes to readingTime or when asked to check its behavior. Do not use for deployment or unrelated project reviews.
---

# Check the reading-time calculator

Read src/reading-time.js and test/reading-time.test.js.
Inspect git diff and git diff --cached for those files.
Run npm test and report the actual result.

Check that empty text still returns at least one minute.
Check backtick and tilde fences, including an unclosed fence.
Check that inline code still counts and wordsPerMinute still works.
For each behavior, point to a test or report the missing coverage.
Check whether the fenced-code regression fails against the original implementation.
Do not change working files to test a historical version. If that comparison
cannot be checked safely, report it as unverified.

Do not edit, stage, commit, or push files.
Return findings with file references, checks performed, and anything unverified.

The name and description frontmatter let Codex find the skill. The remaining Markdown describes the procedure. No script is needed for this one.

In Codex, type $ and select check-reading-time, or send:

$check-reading-time
Review the current calculator and tests. Report findings without changing files.

Check the activity in the conversation. Codex should read the source and tests, inspect the diff, and run npm test. A report saying “looks good” without a test command hasn’t completed the procedure. It should also say if it couldn’t run a check.

Try the skill with the unwanted minimum change from our recovery exercise. It should report a failing test. Restore the change afterward using the reviewed recovery steps. This gives you a way to check the skill against a known failure.

Codex detects skill changes automatically. If the skill doesn’t appear in /skills, check its filename and frontmatter, then restart the client. Project skills belong under .agents/skills/; personal skills belong under ~/.agents/skills/. Avoid duplicate same-name skills, because Codex doesn’t merge them. The skill authoring guide documents discovery and invocation.

Use a read-only session to restrict local command writes alongside the skill’s review-only instructions. A skill itself does not enforce permissions.

Install plugins

Plugins bundle several Codex capabilities. A plugin can contain skills, MCP servers, hooks, browser features, and other resources.

Browse them from the Plugins section:

Browsing available Codex plugins

The directory shows installed plugins and services you can connect. Open one to see the apps and skills it provides. ChatGPT and Codex share the same plugin directory, and I explained how to build and publish one (a plugin.json plus MCP servers and skills) in how to create and publish a ChatGPT plugin.

An installed plugin in the Codex desktop app

The Netlify plugin, for example, includes an app connection and a set of deployment skills. Once it is connected, you can click Try now or mention Netlify in a prompt.

Mentioning the Netlify plugin in a Codex prompt

Cloudflare, Vercel, Render, and Railway offer something similar, as a plugin or an MCP server. I compared them in Cloud platform plugins and skills for AI coding agents.

Some plugins work entirely on your computer. Others connect to an external service and ask you to authorize an account, so check what a plugin can access before installing it. Read the install dialog’s access and data-sharing details before connecting it.

The permissions dialog shown before installing the Netlify plugin

One plugin worth knowing about is Codex Security. It scans a repository for vulnerabilities, validates the plausible findings, and gives you evidence and remediation guidance for each one. Install it from Plugins and a Security item appears in the sidebar, where you set up scans and review the findings. Only scan code you own or have permission to assess.

The same scanner exists as a standalone CLI. I covered it in How to scan your code with the Codex Security CLI.

Use hooks for mechanical rules

Hooks run commands at specific points while Codex works. I use them for mechanical jobs such as logging completed work, checking a command before it runs, or validating a file after an edit.

You define them in ~/.codex/hooks.json, or in a .codex/hooks.json inside the project.

The one I use every day is a PreToolUse hook. Before Codex runs a git commit, it installs a Git post-commit logger in the repository, so every commit lands in the same plain text work log I keep with Cursor. I described the setup in How I use the same Git work log with Codex and ChatGPT.

Advice Codex needs to remember belongs in AGENTS.md or a skill instead.

Hooks can execute code. Review and trust them before enabling them, especially when they come from a plugin.

Local work, worktrees, and handoff

When you start a desktop chat for a Git repository, you can work in your normal local checkout or an isolated Git worktree.

Choosing a worktree for a new Codex task

A worktree gives the chat a separate copy of the repository. Several agents can then work on the same repository without editing the same checkout.

Codex-managed worktrees live under $CODEX_HOME/worktrees by default. Tracked files are present, but ignored files such as .env are not copied unless you list them in .worktreeinclude.

# .worktreeinclude
.env
.env.local

You can hand a chat from a worktree to your local checkout, or move local work into a worktree. Codex takes care of the Git operations behind the move.

I normally work locally, one task at a time. I want direct control of the current checkout.

I use worktrees when tasks are genuinely independent. I still avoid sending two agents into the same files because I would have to merge both sets of decisions afterward.

I explain the underlying Git feature in my Git Worktrees guide.

Split work across subagents

Codex can spawn subagents. Each one is a separate agent that takes one part of the job, runs in parallel with the others, and reports back to the main chat. Ask explicitly when you want work delegated, and check the capabilities available in your current client.

Subagents keep investigation output in their own threads and return summaries. The main chat can then work with the findings instead of every test log and stack trace. Independent work can also finish sooner when it runs in parallel.

Say how to split the work and what each agent should return:

Review this branch against main with three subagents: one for security risks,
one for missing tests, one for maintainability. Wait for all three, then
summarize the findings by category with file references.

Use them for read-heavy work: exploration, tests, triage, review. Be careful with several agents writing code at the same time, because they step on each other’s changes. Each subagent does its own model and tool work, so the run costs more tokens than a single agent would.

Subagents inherit the permission mode of the chat that spawned them. Set it before you delegate. In the CLI, /subagents switches between the running subagent threads.

You can also define your own agents. Put one TOML file per agent in ~/.codex/agents/, or in the project’s .codex/agents/. Each file has a name, a description, and instructions, and can set its own model and reasoning effort:

# .codex/agents/reviewer.toml
name = "reviewer"
description = "Reviews a diff for correctness, security, and missing tests."
model_reasoning_effort = "high"
developer_instructions = """
Review without editing files. Lead with concrete findings and skip
style-only comments unless they hide a real bug.
"""

Asking an agent to review without editing describes its job; it does not create a separate sandbox. You can give an explorer a cheaper model and a reviewer higher reasoning.

Create scheduled tasks

Scheduled tasks run a prompt later, or repeat it on a schedule. You can ask Codex to create one or set it up from the Scheduled section in the app.

For a standalone project task, choose the project, prompt, cadence, model, and execution environment. You can also schedule follow-ups inside an existing chat, which keeps that chat’s context. Use a standalone task when each run should be independent.

Editing a scheduled Codex task

Useful scheduled tasks include:

  • scan recent commits for likely bugs
  • summarize yesterday’s Git activity
  • check outdated dependencies and propose safe upgrades
  • draft a weekly changelog
  • check CI failures

Try the prompt in a normal chat first. Refine it until the result is useful without repeated corrections. I also wrote what would make an overnight agent useful before leaving one running.

For local projects, the computer must be on and the desktop app must be running. Scheduled tasks use your sandbox settings, and unattended work cannot stop to negotiate every action. Give them the narrowest access that lets them succeed.

In a Git repository, a scheduled task can run in your local checkout or on a dedicated background worktree. Pick the worktree unless the task must touch the files you are editing right now. The unattended changes then stay away from your unfinished work.

You can also name the skill a task should use by writing $skill-name in its prompt. The task no longer depends on Codex picking the right skill on its own.

The skill provides the procedure. The schedule decides when to invoke it.

Prepare a scheduled agent taskTest a procedure manually before scheduling it, give the scheduled task suitable access, and inspect its outputs before enabling publication.NoYesWrite a narrowpromptRun it manuallyUseful andrepeatable?Choose schedule andenvironmentReview firstunattended result

For a dependency check, I would start with a report. I would let it list outdated packages and describe risks, while keeping upgrades and deployment as separate decisions. After several useful runs, I could decide whether to automate more of the workflow.

Use Codex from the terminal

The CLI runs Codex inside your terminal. Once you know the desktop workflow, it feels familiar. I wrote a separate guide on how to use the Codex CLI if you want the full tour.

I use it when I’m already working in a shell, or when I connect to a remote server over SSH. I go back to the app when I want its browser, diff, file panels, and multiple chats.

On macOS and Linux, install it with:

curl -fsSL https://chatgpt.com/codex/install.sh | sh

See the official CLI setup guide for Windows and the other installation options.

Move into a project and run:

cd ~/Sites/my-app
codex

The first time, Codex asks you to sign in with ChatGPT or use an OpenAI API key. ChatGPT sign-in uses the Codex allowance included with your plan. An API key bills usage through the OpenAI API.

Codex running in the terminal

You can open the interactive interface with a prompt already filled in:

codex "Explain how authentication works in this project. Don't change anything."

For a non-interactive task, use codex exec. From the reading-time project, this runs the same test suite and prints a final report:

codex exec --sandbox read-only "Run npm test and summarize any failures. Do not edit files."

This exercise needs no generated files, so read-only access is enough. A different project’s test runner might write a cache or build output; use --sandbox workspace-write when that is part of the job.

Progress goes to standard error and the final answer goes to standard output. To save the answer, add -o test-report.md. Your shell or the CLI output option writes that report; the read-only sandbox limits the agent’s commands. A clean exit alone doesn’t prove the tests passed, so read the reported result.

The non-interactive mode guide covers structured output and automation. Older examples using --full-auto need updating: that flag is no longer supported.

The current directory becomes the CLI workspace. Run /init if you want Codex to generate a starting AGENTS.md, then edit the file for your project.

Running the init command in the Codex CLI

Codex writes the generated project instructions to AGENTS.md.

An AGENTS.md file generated from the Codex CLI

Use /mention to add a file or folder to the prompt:

/mention src/lib/auth.js

You can pass one or more images with -i or --image:

codex -i screenshot.png "Explain this error and suggest the smallest fix"
codex --image before.png,after.png "List the visual regressions"

Web search normally uses an OpenAI-maintained cache. In full-access configurations, it defaults to live results. Pass --search when you need live results for one run:

codex --search "Summarize the latest release notes for this dependency"

Set web_search = "live" in config.toml to make that the default, or web_search = "disabled" to turn the tool off.

Run /mcp to inspect active MCP connections. Use /skills to browse skills and /plugins to browse installed and available plugins. You can add an MCP server with codex mcp add. Start a new CLI session after installing a plugin, otherwise its tools and skills will not be available yet.

Fix the sign-in problem before changing code

If the client won’t start useful work, check the account and environment first:

ProblemFirst check
codex isn’t foundOpen a new terminal and check the install directory is on PATH
The app and CLI show different accessConfirm the same account, workspace, and sign-in method
API-key usage appears on a bill instead of the planCheck which sign-in method is active; API billing is separate
Cloud work is unavailable with an API keyUse an eligible ChatGPT sign-in for cloud features
A managed account blocks a featureCheck the workspace policy with its administrator
A local tool works on your laptop but fails in cloudCheck the cloud setup and its available credentials and services

Run codex doctor for local installation, configuration, and authentication diagnostics. Read the report before sharing it, and keep credentials out of prompts or screenshots. The authentication guide covers supported login methods and environments.

Make a change from the CLI

In the terminal, give Codex the same requirements and checks you would use in the app.

In this example I asked it to add a Counter component with increment, decrement, and reset controls, then use it from App.tsx.

Asking the Codex CLI to add a Counter component

Codex inspected the project, changed the files, and reported the result in the same terminal session.

The Counter component completed by the Codex CLI

You can review those files in your usual Git client too. Here they are in GitHub Desktop.

Reviewing Codex CLI changes in GitHub Desktop

The CLI commands I use most

Type / to open the command list. It changes as Codex adds features, but these are the commands I use most:

  • /init creates a starting AGENTS.md
  • /plan enters Plan mode
  • /goal starts or manages a persistent goal
  • /model changes the model and reasoning level
  • /permissions changes what Codex can do without asking
  • /mention adds a file or folder to the prompt
  • /diff shows the Git diff
  • /review starts a separate reviewer on a diff: against a base branch, the uncommitted changes, one commit, or with your own instructions
  • /subagents switches between running subagent threads
  • /compact summarizes a long chat to recover context space
  • /status shows the current model, permissions, workspace, and context usage
  • /usage shows account usage
  • /resume continues a saved chat
  • /fork branches the current chat without losing the original
  • /mcp inspects active MCP connections; /skills and /plugins browse their respective catalogs
  • /quit exits

The CLI also has normal subcommands:

codex resume
codex review --uncommitted
codex exec "Run the tests and return only the failures"
codex doctor

Run codex --help and codex <command> --help for the version installed on your computer. The official command reference documents every option.

Other ways to use Codex

The IDE extension

The Codex IDE extension puts the agent beside your editor. It can use open files, your current selection, and the repository as context.

I would use it when a task starts from code already open in the editor. I prefer the desktop app when I want the diff, terminal, browser, and several chats visible together.

Codex cloud

Codex cloud runs work in an isolated environment. You can delegate a task without keeping your computer busy. I walk through the setup in How to use Codex Cloud.

Cloud requires ChatGPT sign-in; API key sign-in supports local work. The cloud environment also needs its own setup. Dependencies, environment variables, and services on your laptop are not automatically present there.

Continue a local task from your phone

Remote access connects your phone to a computer already running the desktop app. The code and local tools stay on that host. This is useful for answering a question or checking a test result while you’re away from the desk.

You need a Mac or Windows computer that stays awake and online, the current desktop and mobile apps, and the same ChatGPT account and workspace signed in on both.

On the computer, open Settings > Connections > Control this Mac or PC, then choose Set up or Add. Complete the requested verification. Scan its QR code with your phone and finish the connection in ChatGPT.

On the phone, open Codex (on Android it’s called Remote). Choose the paired host, open the reading-time project, and continue its existing chat. Ask for a status update before sending another coding task:

Show the current task status, the latest npm test result,
and any question waiting for my decision. Don't change files.

The host’s permissions and credentials still apply. If it sleeps or goes offline, that local connection cannot use its files. Keep substantial code review for a screen where you can read the diff comfortably.

After the exercise, return to Settings > Connections on the host. Review the paired devices and remove a connection you no longer want to allow. Don’t share the pairing QR code or code with another person.

Mobile access starts from the desktop setup. Installing the CLI alone doesn’t complete that pairing flow. OpenAI’s remote connections guide covers current platform support, verification, and disconnecting devices.

A real debugging workflow

I once woke up to an angry email because the unsubscribe link for my newsletter did not work. The entire server was down, and the disk was 99% full.

I could have given Codex SSH access. This was a production server with almost no free space, so I wanted to see every command. I ran each command myself and pasted the output back.

The loop looked like this:

I pasted df -h
Codex suggested the next safe inspection
I ran it
I pasted the result
Codex narrowed the search

We found that the Sendy database used only 528 MB. MySQL binary logs used around 41 GB.

Codex told me not to delete files manually from /var/lib/mysql. It gave me the MySQL command to purge old binary logs safely, and the disk went from 99% used to 41% used. The important detail was using the database’s own maintenance command, after checking which logs could be removed. I wrote the full session in How I fixed a full Ubuntu server disk with Codex.

I don’t let the agent execute everything on a risky system. In this case Codex guided the investigation, while I ran one command at a time and made the final decisions.

What I learned building a full app with Codex

I also used Codex to build a local web app that generates multi-page comics from a story and reference photos.

I started with a detailed prompt about characters, story projects, storyboards, image generation, exports, and local storage. Later I changed the stack, added reusable comic styles, switched the image API, and fixed mistakes I only noticed when I used the app.

The first prompt produced a lot of software, but it wasn’t the exact product I had in mind. Some product decisions in my detailed prompt were wrong, and I only discovered missing requirements by using the app.

The generated UI needed more work too. When image generation failed silently, I asked Codex to add progress and error messages before touching the API. With the failure visible in the app and the logs, we could see what needed fixing.

That experience is why I now give Codex one coherent outcome at a time. I make the result observable, try it myself, review the changes, and continue from there.

What I don’t like about Codex

The naming. The app is called ChatGPT, Codex is a mode inside it, and most documentation pages describe ChatGPT Work and Codex together. It takes a while to work out which sentence applies to you.

Goal mode is impressive, but it isn’t how I want to work. After the PocketBase experiment, I’d rather spend that budget on ten well-scoped tasks I can review one by one.

The built-in browser doesn’t know my logins. It has its own profile, so a page behind Google sign-in means signing in again inside Codex. The browser extension can drive your real Chrome instead, at the price of an extension that can read and change data on every site you visit.

Computer Use only exists in some regions, and it’s a plugin rather than a built-in, so the setup has more steps than the browser.

Scheduled tasks for local projects need the computer awake and the app running. A task set for 7am does nothing if the laptop is closed. For anything that must run no matter what, I still use a cron job on a server or a scheduled GitHub Action.

When I pick Codex over Cursor or Claude Code

I use all three. Cursor gets most of my days, because I’m in the editor anyway and I like a local agent that works on my checkout, one task at a time. Claude Code is my other terminal agent, and the one I ran on a disposable server to build and ship a small app from the same box.

Codex wins for me when:

  • I’m working on something visual. Clicking an element in the built-in browser and describing the change beats writing a paragraph about where it is.
  • I want a task to run on a schedule, or unattended in a worktree while I do something else.
  • I want the whole loop in one window: plan, change, terminal, browser, diff, commit.
  • My ChatGPT plan includes it. If yours includes Codex too, you can try it within that plan’s allowance.

With all three I keep the same habit of reviewing one outcome at a time. I compared the applications in Codex vs Claude Code vs Cursor, and the models in Which AI model is best for coding?. For a comparison of the terminal tools on the same task, see OpenCode vs Codex CLI on one bug fix.

My Codex workflow

This is the loop I follow for most project work:

  1. Open the correct project.
  2. Ask Codex to inspect the relevant code without changing it.
  3. Use Plan mode if the task crosses several files or has unclear decisions.
  4. Review the plan.
  5. Ask Codex to implement one coherent outcome.
  6. Let it run the tests and build.
  7. Verify the behavior in the browser or app.
  8. Read the full diff.
  9. Ask for one final review.
  10. Commit and push only when I understand the result.

For a long job with a precise end state, I use Goal mode. If a workflow becomes stable and repetitive, I turn the instructions into a skill and test it before scheduling anything.

None of this is specific to Codex. I wrote down where the loop comes from, after six months of working with Cursor, Claude Code, and Codex, in What I learned in the past 6 months about using agentic AI.

How I would start on an existing project

I would pick a bug I can reproduce, create a Git checkpoint, and ask Codex to find the code responsible before editing it. Then I would give it one change and a concrete check.

For a web form, that check might be submitting an empty value, correcting it, saving, and reloading the page. For a CLI, it might be running the command with a known input and checking its exit status as well as its output.

When Codex finishes, I would use the feature myself and read the diff. If I can’t explain why a changed file belongs in the task, I would ask before committing it.

Try this with a small change in a repository you already know. Having a bug you can reproduce makes it much easier to judge the result.

Want me to talk about your product? You can sponsor this site.

Related posts about ai: