Start a new project with Codex
Starting a new project with Codex means turning a short spec into a repository whose gates can prove agent work correct: Codex scaffolds only the tooling, deliberate breaks show each gate can fail, AGENTS.md records the commands that define “done”, and a setup script makes every worktree runnable before the first feature ships.
This page is for the developer who owns a new service from day zero, and for the tech lead who wants every new repository on the team to start from the same verifiable baseline. The situation: the billing service got approved this morning, the spec is a page of notes, and the first real feature is due in two weeks. A scaffold that looks complete but has a test runner that passes with no tests will let every later agent change through unchecked.
What you’ll walk away with from a Codex project bootstrap
Section titled “What you’ll walk away with from a Codex project bootstrap”- A six-step order for bootstrapping a repository with Codex, from spec to the first merged feature
- Five copy-paste prompts: spec review, tooling scaffold, gate check,
AGENTS.mdand the first feature - A
verifyscript and a CI job that prove agent work without anyone reading every generated file - A worktree setup script, so parallel Codex tasks start with dependencies installed
- Recovery steps for the ways a Codex bootstrap goes wrong
Before you start, install Codex and sign in (Install Codex); your first Codex task covers the basics this page assumes.
Which Codex surface should you bootstrap from?
Section titled “Which Codex surface should you bootstrap from?”Codex runs the same agent in several clients; the desktop app and the CLI read the same ~/.codex/ home, so the choice is about how you want to watch the work. Surface details below were checked against codex-cli 0.157.1 on 2026-09-26.
| Surface | Use it for the bootstrap when | How to start |
|---|---|---|
| Desktop app (macOS, Windows) | You want the diff in a review pane and several threads side by side | codex app, then add the project folder and start a Local thread for the scaffold |
| CLI | You work in the terminal or on Linux, where codex app does not exist | cd into the folder and run codex |
| Codex cloud | Not for day zero | A cloud task needs a hosted repository and a cloud environment; use it once the baseline is pushed |
The desktop app now ships inside the ChatGPT desktop app as a Codex mode, per Neowin’s report of 2026-07-09 (secondary source); the CLI accepts either Codex.app or ChatGPT.app on macOS. App-specific workflow, such as local versus worktree threads, is covered in Codex desktop app mastery.
Codex’s bundled default model is GPT-6 Astra at low reasoning effort; for signed-in accounts the server can choose a different default model (since codex-cli 0.154.0), so check with /model. The models hub lists current defaults. Scaffolding does not need more. Plan mode, which step 1 uses, has its own effort setting: it ignores model_reasoning_effort and reads plan_mode_reasoning_effort, which falls back to the built-in Plan preset (medium) when unset (checked against codex-cli 0.157.1 source, codex-rs/core/src/config/mod.rs, on 2026-09-26). For the spec review, start Codex with codex -c plan_mode_reasoning_effort="high" (or set the key in ~/.codex/config.toml) before you consider another model.
Bootstrap the project in six steps
Section titled “Bootstrap the project in six steps”-
Create the repository and write the spec before Codex writes code.
Terminal window mkdir -p ~/projects/billing-service && cd ~/projects/billing-servicegit init -b mainmkdir docs && touch docs/spec.mdWrite
docs/spec.mdyourself: what the service does, the stack you have already chosen, what is out of scope, and three to five acceptance criteria for the first feature, each phrased so a test can check it. Fifteen minutes here saves a scaffold built on the agent’s guesses. Then let Codex attack the spec in Plan mode (/planin the CLI), which proposes without editing files.For the stack and architecture decisions the review surfaces, see architecture planning with Codex.
Answer the questions in
docs/spec.md, not in the chat. The spec is the file every later task reads; the conversation is gone after the session. Then commit it, so the repository has aHEADthat every later diff and review compares against:Terminal window git add docs/spec.md && git commit -m "Add service spec" -
Scaffold the tooling only, in your checkout. Start Codex in the project folder and accept the trust prompt: since codex-cli 0.150.0, an untrusted project does not supply its
AGENTS.md.Terminal window cd ~/projects/billing-servicecodexRun
codex app(on macOS the CLI also opensChatGPT.appif that is what you have installed), add~/projects/billing-serviceas a project and start a Local thread. The scaffold runs in a local thread because you install and verify it in this checkout yourself; a worktree would start without the files you are about to create.Run the install yourself. Codex’s default
workspace-writesandbox restricts network access, so an install inside the session either fails or needs an approval to leave the sandbox:Terminal window npm installdocker compose up -d --waitnpm run db:migratenpm run verify; echo "exit code: $?"Before you commit the scaffold, check that every new dependency is real and current with
npm view PACKAGE_NAME versionfor anything you do not recognise. A dependency name the model invented is a supply-chain risk, not a typo; dependency verification covers the full check. Then runcodex review --uncommittedfor a second look at the scaffold, and onceverifyexits 0, commit a checkpoint so step 3 has a clean state to revert to:Terminal window git add -A && git commit -m "Scaffold tooling" -
Prove every gate can fail. A green
verifyon day zero proves nothing until you have seen each gate go red. This is the step that lets you trust later agent work without reading it.The integration gate needs the local database, which the
workspace-writesandbox cannot reach on its own. Approve the escalation when Codex asks to runnpm run verifyoutside the sandbox, or make the four breaks and runverifyyourself; otherwisetest:integrationfails for a sandbox reason and the table reports a false “yes”.A “no” in that table is the most valuable output of the whole bootstrap. Fix the gate, then rerun the prompt.
-
Write
AGENTS.mdfrom what is now true. Run/init(“create an AGENTS.md file with instructions for Codex”) to get a draft, then tighten it with the prompt below. Codex will want to rerun the setup commands, which need network and Docker: approve those escalations, or run the commands yourself and paste each exit code into the chat. Codex readsAGENTS.mdbefore doing any work, so every later task, local or cloud, inherits these commands.The result should look close to this:
# Billing serviceExpress + TypeScript billing API on PostgreSQL via Drizzle ORM. The spec, includingacceptance criteria, is docs/spec.md; read it before changing behaviour.## Setupnpm installdocker compose up -d --waitnpm run db:migrate## Definition of done- `npm run verify` exits 0 (lint, typecheck, unit and integration tests).- New behaviour has a test that fails without the change.## Conventions- Named exports only. async/await, no raw promise chains.- Validate every route input with Zod. All database access through Drizzle; no raw SQL.## Boundaries- Do not edit .github/workflows/ or existing tests to make a check pass. Ask first.## Review guidelines- Flag missing input validation, error responses that leak internals, console.log outside scripts/.Test the file instead of trusting it: start a new session and ask “What command proves a change is done here, and which files may you not edit?” If the answer does not quote
npm run verifyand the boundaries line, Codex is not reading the file; see the failure modes below. For layering global and nested files, see the AGENTS.md quick start. -
Make every worktree runnable, then commit the baseline. A managed worktree starts from committed files only: no
node_modules/, no.env, no uncommitted edits (tested on codex-cli 0.157.1 in isolated Codex tasks with Git worktrees). Commit a setup script so every worktree, whoever creates it, bootstraps the same way:#!/usr/bin/env bash# scripts/setup-worktree.sh: run from inside a fresh worktree, in your own terminalset -euo pipefailMAIN=$(git worktree list --porcelain | awk 'NR==1 {print $2}') # main checkout is listed firstID=$(basename "$(dirname "$PWD")") # managed worktrees sit at $CODEX_HOME/worktrees/<id>/billing-serviceDB_PORT=$(( 5500 + $(printf '%s' "$ID" | cksum | cut -d' ' -f1) % 400 )) # stable port per worktreeSRC="$MAIN/.env"; [ -f "$SRC" ] || SRC=.env.example # local values, else committed defaultsgrep -v -E '^(COMPOSE_PROJECT_NAME|DB_PORT)=' "$SRC" \| sed -E "s#^(DATABASE_URL=.*:)[0-9]+/#\1$DB_PORT/#" > .envgrep -q '^DATABASE_URL=' .env || { echo "no DATABASE_URL in $SRC; add it to .env.example" >&2; exit 1; }printf 'COMPOSE_PROJECT_NAME=billing-%s\nDB_PORT=%s\n' "$ID" "$DB_PORT" >> .envexport COMPOSE_PROJECT_NAME="billing-$ID" DB_PORT # own Compose project and databasegit submodule update --init --recursive # no-op without submodulesnpm cidocker compose up -d --waitnpm run db:migrateAdd one line to the Setup section of
AGENTS.md: “In a new worktree, runscripts/setup-worktree.shfirst.” Then commitAGENTS.mdand the setup script, and push:Terminal window chmod +x scripts/setup-worktree.shgit add -A && git commit -m "Add AGENTS.md and worktree setup script"git remote add origin git@github.com:YOUR_ORG/billing-service.gitgit push -u origin mainYOUR_ORGis your GitHub organisation or user. Once the first CI run has finished (a check name appears only after it has run), make the CI job a required check: on GitHub, open Settings → Rules → Rulesets → New branch ruleset, targetmain, turn on Require status checks to pass and add the CI job. Classic Settings → Branches protection rules work too.If the desktop app on your machine offers a per-project setup script for worktree threads, point it at this file rather than duplicating the commands; the file stays the single source.
-
Ship the first feature from a worktree. Start it isolated from your checkout:
codex --worktreein the CLI, or a Worktree thread in the desktop app. A managed worktree starts on a detachedHEAD, so the prompt creates a branch first.Before you send the prompt, prepare the worktree: run
scripts/setup-worktree.shinside it in your own terminal, or approve the escalation when Codex asks. The script installs packages and talks to Docker, which theworkspace-writesandbox does not allow on its own.
How do you verify the bootstrap without reading every generated file?
Section titled “How do you verify the bootstrap without reading every generated file?”The scaffold is a few hundred lines you did not write. You do not need to read them if each claim below has evidence, and the evidence is cheap to produce.
| Claim | Evidence | Who signs off |
|---|---|---|
| The gates work | The step 3 table: each gate failed on its breaking change and passed after the revert | You, before you write AGENTS.md |
| The code does what the spec says | One test per acceptance criterion, shown failing before the change and passing after it | You approve the tests; the tests approve the code |
| Nothing leaked outside the brief | git status --short, which also lists untracked files, shows only files the prompt named | You |
| Dependencies are real | npm view for each unfamiliar package, and a committed lockfile | You, or a dependency-review action in CI |
| The change is clean on a second look | codex review --uncommitted on the scaffold before its checkpoint commit, codex review --base main on the feature branch | A second model pass, then a human on the pull request |
| It works outside your laptop | The CI job runs npm run verify against a fresh PostgreSQL container | CI, as a required check |
Read code only where this table leaves a gap: a file the evidence does not cover, a test that looks weaker than its criterion, or a review finding you cannot dismiss from the diff alone. Executable acceptance criteria covers turning spec lines into tests, and making a codebase agent-ready scores the properties this bootstrap sets up.
What breaks when you bootstrap a project with Codex?
Section titled “What breaks when you bootstrap a project with Codex?”Codex ignores AGENTS.md. The project is untrusted, CODEX_HOME points at a different home in one client, or you started Codex outside the repository. Recovery: start Codex from the repository root and accept the trust prompt; check echo $CODEX_HOME in the shell and the app’s environment; run codex doctor to see what the CLI reads. Then repeat the “which command proves a change is done” test from step 4.
npm install fails inside the session. The workspace-write sandbox restricts network access by default. Recovery: run installs in your own terminal, as step 2 does, and tell Codex in the prompt not to install. Do not switch to --dangerously-bypass-approvals-and-sandbox to get around it; use that flag only inside a disposable, network-restricted sandbox, such as a throwaway container.
verify is green on an empty project. The test runner was told to pass with no tests, or the only test asserts a constant. Recovery: rerun the step 3 prompt; any gate that does not fail gets fixed before anything else lands.
The scaffold grew files you did not ask for. README badges, a CONTRIBUTING.md, a sample feature. Recovery: git status --short to list them, git clean -nd to preview removing untracked files and directories, then git clean -fd once the list is right. Keep “Do not create files I did not list” in the prompt.
A dependency does not exist or is years old. The model wrote a plausible package name or an old major version from memory. Recovery: npm view PACKAGE_NAME version on each unfamiliar entry, remove what does not resolve, and ask Codex to replace it with a package you name.
The worktree task cannot run tests. The worktree has no node_modules/, no .env, or the database is not up. Recovery: run scripts/setup-worktree.sh inside the worktree; if the task needed uncommitted work, commit it and start a new worktree from the updated branch.
Worktrees share, and overwrite, one database. Every managed worktree sits at $CODEX_HOME/worktrees/<id>/billing-service, so its folder has the same name as your main checkout. Docker Compose derives the project name from that folder name, so docker compose up in a worktree attaches to, or recreates, the main checkout’s containers, and db:migrate runs a feature branch’s migrations against the database you develop on. Nothing fails loudly; the data just changes under you. Recovery: give each worktree its own Compose project and port, as the step 5 script does with COMPOSE_PROJECT_NAME=billing-<id> (or docker compose -p) plus a per-worktree DB_PORT and matching DATABASE_URL, with the port published from "${DB_PORT:-5432}:5432" in docker-compose.yml. Ephemeral environments for agent tasks covers full per-task stacks.
AGENTS.md grows until nobody trusts it. Every correction becomes a new line. Recovery: keep commands, the definition of done and boundaries in AGENTS.md; move architecture notes to docs/ and point to them. AGENTS.md optimization covers the pruning pass.
Where to go next after your first Codex worktree feature
Section titled “Where to go next after your first Codex worktree feature”Starting the same kind of project in another tool? See start a new project with Claude Code or start a new project with Cursor. For an existing codebase rather than a new one, read understanding codebases with Codex.