MC.
Build log / 7 daysBack to résumé
Engineering · AI-assisted development

Building an application with Claude Code and Codex in a week

A practical account of taking an idea from an empty repository to a tested, deployed, multi-client application—with two coding agents, a short feedback loop, and a bias toward reversible decisions.

A reconstruction from the project’s commit history · July 2026

A week is enough to build a surprisingly complete first version if “build” means more than making a screen look convincing. The useful finish line is a system that can store real data, survive bad input, support more than one client, be tested, and be operated by someone who did not write every line.

This article describes the process without relying on the application’s subject matter. The repository’s commits record what changed and when, but not which agent produced each change. The division of labor below is therefore a workflow pattern—not an attempt to assign individual commits retroactively.

The central lesson: AI made implementation faster, but the biggest acceleration came from keeping the work legible: explicit phases, small commits, written decisions, tests at the boundaries, and frequent human review.

Start with a thin vertical slice

The first evening established the shape of the system rather than chasing features. The sequence in the history was deliberate:

That produced a vertical slice early. It was not polished, but it answered the important questions: Can a user create data? Does it come back after a reload? Is it scoped to the right account? Can the behavior be tested without clicking through the browser?

Clientintent + feedback APIauth + validation Databasesource of truth Testsproof at edges feedback closes the loop
A thin slice makes architectural mistakes visible while they are still cheap to change.

Use two agents as a relay, not a lottery

Claude Code and Codex are most useful when they have different jobs in the loop. Asking both to “build the app” creates duplicated effort and conflicting assumptions. A better pattern is a relay:

  1. Frame the task. Describe the user outcome, constraints, acceptance criteria, and files that are in scope.
  2. Explore and propose. Have one agent inspect the repository, trace the relevant code paths, and identify the smallest coherent change.
  3. Implement in a bounded slice. Let the other agent make the change, including tests and documentation where the behavior warrants it.
  4. Review the diff. Ask for an adversarial pass: authorization, data ownership, failure modes, migrations, mobile behavior, and stale docs.
  5. Run the checks. Tests, lint, type checking, and a focused manual smoke test are part of the task—not a later cleanup phase.

The human remains the product manager and release engineer. Agents can propose a good implementation; they cannot decide what “good enough to ship” means without a clear boundary.

The week, reconstructed from the commits

Day 1 — Baseline and persistence
Tooling, tests, CI, a local persistence experiment, then an authenticated API with tenant isolation. The prototype was useful because it clarified the data model; it was not treated as the final architecture.
Day 2 — Two clients
The web client was wired to the server, then a native client was added against the same API. Shared contracts mattered more than shared UI code: both clients could evolve independently while reading the same source of truth.
Day 3 — Real user workflows
Forms, editing, deletion, validation, account recovery, confirmation messaging, and a narrowly scoped sharing flow were added. Small fixes in the history—hidden fields, stuck saves, date-time behavior—show why device-level testing belongs in the first week.
Day 4 — Offline and operational safety
The native client gained a local read-through cache and an outbox for writes. Idempotency was added at the API boundary so reconnecting would not duplicate a submission. Backups, retention, and failure alerts followed.
Day 5 — Product decisions become code
Limits, entitlements, notifications, data export, deletion, and admin controls were implemented as explicit server-side rules rather than UI-only behavior. This is where a demo starts becoming a product.
Days 6–7 — Deployment and hardening
The hosting path was made repeatable, static assets were moved to edge hosting, deep links were fixed, health checks were made database-aware, and the API environment was moved to redundant infrastructure with rolling deployment procedures.

Architecture: one source of truth, several delivery surfaces

The system settled on a simple boundary: clients own presentation and local experience; the API owns authorization, validation, and business rules; the database owns durable state. Background jobs and object storage sit behind the API rather than becoming second application paths.

Web clientfast iteration Native clientoffline-first UX Application APIauth · rules · validation Database Object storage Jobs + monitoring
The architecture is intentionally boring: one API boundary keeps authorization and invariants from drifting between clients.

Decisions that paid for themselves

Prototype locally, then graduate

A local persistence layer provided momentum on day one. Moving to the API early prevented the prototype from becoming a hidden production dependency.

Keep clients additive

The native client used bearer authentication while the web client retained its cookie flow. That reduced migration risk and kept the shared API contract explicit.

Make writes idempotent

Offline retries are normal, not exceptional. A client-generated request identity turned a network problem into a safe retry instead of a duplicate record.

Prefer additive migrations

Rolling deployments mean old and new server versions can briefly coexist. Expand/contract database changes let that transition happen safely.

Hide protected routes

Unauthorized data routes returned a non-enumerating response. This reduced account and endpoint discovery without putting security logic in the clients.

Write the runbook while building

Deployment, backups, restore, incident response, and release steps were documented beside the code. Documentation became an operational test of whether the system was understandable.

What the agents did not replace

The most important work was judgment:

AI is excellent at turning a precise request into a lot of coherent code. It is much less reliable at noticing that the request itself is underspecified, that a “temporary” shortcut has become a dependency, or that a successful test is testing the wrong thing.

A repeatable working loop

For a new feature, the effective prompt was close to a small engineering ticket:

Outcome: a signed-in user can create and later retrieve one record.
In scope: API route, validation schema, migration, client form, tests.
Constraints: isolate by account; preserve existing auth; additive migration.
Acceptance: happy path, invalid input, anonymous request, wrong-account request,
retry after timeout, and a focused UI smoke test.
Before editing: inspect the current route, schema, tests, and deployment notes.
After editing: show the diff, run checks, and list any remaining assumptions.

That format gives both agents enough context to be useful and enough constraints to be reviewable. It also makes context switching cheap: the next session can start from the ticket, the diff, and the failing test rather than from a long conversational history.

The real speed multiplier

A week-long build with Claude Code and Codex is not a shortcut around software engineering. It is a way to spend more of the week on the parts that matter: boundaries, feedback, tradeoffs, and proof.

Start with a vertical slice. Keep the architecture plain. Give each agent a bounded role. Make every important behavior executable as a test or a runbook step. Ship the smallest system that can teach you what to build next.