Skip to content

Start a new project from the terminal with Claude Code

To bootstrap a project with Claude Code, commit an empty repository, approve a plan in plan mode, let Claude run the framework’s generator and customize the output, then make it prove the scaffold works with one verify script that CI also runs. A fast subset gates every reply through a Stop hook, and /init records the conventions in CLAUDE.md.

This page is for developers starting a service from an empty directory, and for tech leads who want every new repository on the team to start from the same gate. The situation: the product manager describes a service in one sentence — “a REST API for user preferences, PostgreSQL, auth, rate limiting, structured logs” — and the usual answer is a day of wiring before any business logic exists. Claude Code writes that wiring quickly. The hard part is that a folder tree proves nothing, so this workflow ends in evidence you can check, not in a tree you hope compiles. You need Claude Code installed and signed in (installation), plus Git and Docker for the walkthrough.

  • A plan you approved before a single file existed: stack, file tree, dependencies, and the acceptance checklist.
  • A scaffold generated by the framework’s own tool where one exists, customized by Claude to your conventions.
  • One command, scripts/verify.sh, that lints, type-checks, tests, boots the service and hits /health. You run it before commits and CI runs it on every push; its fast half, scripts/verify-fast.sh, runs in a Stop hook before Claude may declare the work done.
  • A CLAUDE.md under the vendor’s 200-line target, plus a recorded launch recipe for the bundled /run and /verify skills.
  • Copy-paste prompts for Express with Drizzle, Next.js, FastAPI, and Phoenix.

Which scaffolding route should Claude take?

Section titled “Which scaffolding route should Claude take?”

Decide this before the first prompt. It changes how much of the output you have to check.

RouteUse it whenWhat you verify
Claude runs the official generator (create-next-app, mix phx.new), then customizesThe framework has a maintained generatorThe diff between the generator output and Claude’s changes, plus the verify script
Claude writes the project from scratchNo generator fits (an Express API, a small worker)Every file is agent-written, so the verify script and the acceptance checklist carry the whole load
Claude copies your team’s template repositoryYour team already has a golden pathOnly the project-specific delta; the template’s own gate is already trusted

The generator route is the default because the boilerplate is deterministic and maintained by the framework authors. Claude’s contribution shrinks to the part that is specific to your project.

Bootstrap a new service from an empty directory

Section titled “Bootstrap a new service from an empty directory”

The walkthrough builds the user-preferences API from the scenario above. The same steps apply to any stack in the next section.

  1. Create the repository and commit before Claude touches it

    Terminal window
    mkdir prefs-api && cd prefs-api
    git init
    git commit --allow-empty -m "chore: empty root"
    claude --permission-mode plan

    The empty commit matters more than it looks. Claude Code checkpoints do not track files changed by Bash commands, and a generator or npm install runs through Bash. Esc Esc and /rewind therefore cannot undo a bad scaffold; git can.

    --permission-mode plan starts the session in plan mode, so Claude explores and proposes without writing files.

  2. Ask for a plan with an acceptance checklist

    A vague prompt such as “create a web app” returns a generic template. Name the stack, the layout, the conventions, and what “done” means.

    Read the plan, not the code that does not exist yet. Check that the acceptance checklist describes behavior you care about. Edit it in the conversation until it does. This checklist is what you sign off later, instead of reading every generated line.

  3. Approve the plan and let Claude scaffold

    Accept the plan and choose the permission mode for the build. With Claude Code v2.1.283 or later (the latest channel), auto mode is the starting mode for interactive terminal sessions: a classifier reviews each action and only risky ones reach you. On the stable channel (v2.1.274 on 2026-09-26), auto mode is the starting mode only on Pro, Max, and Team plans; Enterprise, API and cloud-provider sessions still start in Manual, so expect more prompts there. Commit when the files are in place:

    Terminal window
    git add -A && git commit -m "chore: scaffold prefs-api"
  4. Make Claude build the gate and prove the scaffold runs

    The final table is your review surface. A checklist item with no test next to it is a gap, whatever the code looks like. Claude is also at its best with a real error in front of it: a failing migration or a version conflict in stderr gives it something precise to fix.

  5. Correct one real gap

    Scaffolds usually miss something specific to how you work. Name it; do not re-describe the whole project.

    The CRUD handlers call Drizzle directly. Put a preferences service layer
    between routes and db so business logic is testable without HTTP, move the
    Zod schemas to src/schemas/, and run ./scripts/verify.sh again.
  6. Record the conventions and the launch recipe

    /init

    /init analyzes the project and writes a starting CLAUDE.md with build commands, test instructions and the conventions it detects; if a CLAUDE.md already exists, it suggests improvements instead of overwriting it. Add the rules it cannot infer — “service layer between routes and db”, “never hand-edit migrations” — and keep the file under 200 lines, the target in Anthropic’s memory documentation. The anatomy of a good file lives in Project initialization: CLAUDE.md and project context.

    Then run /run-skill-generator. This bundled skill gets the app running from a clean environment and writes the recipe as a per-project skill at .claude/skills/run-<name>/ (commit it with the scaffold), so the bundled /run and /verify skills start the service correctly next time instead of guessing how to bring up Postgres.

After step 6 you have a repository whose claims are checkable: a plan you approved, a gate that has been seen to fail and to pass, and a mapping from each acceptance item to its proof.

How do you keep the gate running without slowing every reply?

Section titled “How do you keep the gate running without slowing every reply?”

CLAUDE.md instructions are advisory; hooks run every time. A Stop hook fires when Claude finishes responding, and exit code 2 prevents Claude from stopping and feeds stderr back to it. The hook fires after every response, including plan-mode answers and plain questions, so wire in only verify-fast.sh (lint, type check, unit tests). Claude then cannot report “done” while that gate is red, and a reply does not wait on Docker. Add it to .claude/settings.json once the scripts exist:

{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && { [ -z \"$(git status --porcelain)\" ] && exit 0; ./scripts/verify-fast.sh 1>&2 || exit 2; }"
}
]
}
]
}
}

Stop takes no matcher. The git status --porcelain guard skips the gate when the working tree is clean, so a question asked after you commit costs nothing; while changes are uncommitted, every reply runs the fast gate, which is why it must stay fast. It counts new, untracked files too; git diff --quiet HEAD would not, and a bootstrap turn that only adds files would end without running the gate. Claude Code caps stop-hook continuations at eight in a row and then ends the turn, so a gate that can never pass does not loop forever. The cap is adjustable with CLAUDE_CODE_STOP_HOOK_BLOCK_CAP, and the hook input’s stop_hook_active field tells your script it is already in a forced continuation. The hooks guide covers PostToolUse formatters and PreToolUse blocks.

The full verify.sh (the fast half plus Docker, migrations and the /health boot) runs before each commit and in CI. Because it calls verify-fast.sh, the Stop-hook gate is a strict subset of the merge gate and the two cannot drift. Because an agent that can edit the gate can also weaken it, route changes to scripts/verify*.sh and .claude/settings.json through human review; protecting the oracle shows how. Who signs off: the developer approves the acceptance checklist and reads the evidence table, not every line. The tech lead owns the stack prompt and the verify contract, so every new repository starts from the same gate.

Each prompt has the same shape as the Express one: generator first, then layout, conventions, a first resource, and the same verify contract.

Make configuration refuse to boot on a bad value

Section titled “Make configuration refuse to boot on a bad value”

A scaffold that emits config files is not done until you have seen the config reject something. Config validation that has never rejected a value is validation you do not have.

Choose permissions for a bootstrap or a throwaway prototype

Section titled “Choose permissions for a bootstrap or a throwaway prototype”

A bootstrap runs many commands: package installs, generators, Docker, migrations. Pick the mode deliberately:

  • Plan mode (--permission-mode plan) for step 2, so nothing is written before you approve.
  • Auto mode for the build on v2.1.283 or later, or earlier on Pro, Max and Team. Set "defaultMode": "auto" under permissions in ~/.claude/settings.json (user settings); Claude Code ignores auto and bypassPermissions as defaultMode in project settings.
  • --dangerously-skip-permissions only inside a disposable container with restricted network egress. The CLI’s own help text recommends it “only for sandboxes with no internet access”. A bootstrap needs the package registry, so allow that host and nothing else, for example in a dev container. Never use it in a repository or on a machine you care about.

Validate the idea in the sandbox, then rebuild the version you keep with the full workflow above. The permissions and sandboxing guide compares the modes across tools.

Connect the database and share team recipes

Section titled “Connect the database and share team recipes”

Two extensions remove guessing during a bootstrap, and they solve different problems. An MCP server is a live connection to a system. A skill is a reusable recipe.

Postgres MCP Pro lets Claude read the live local schema and explain plans instead of guessing column names. It is a Python package, so it runs through uvx, and --access-mode=restricted keeps it to read-only transactions. Point it at the local Docker database, never at production. Its release cadence has stalled — the latest PyPI upload is 0.3.0 from 2025-05-16 (checked 2026-09-26) — so re-check the repository before you build it into a team template:

Terminal window
claude mcp add postgres -e DATABASE_URI="$DATABASE_URL" -- uvx postgres-mcp --access-mode=restricted

For GitHub, gh repo create from Claude’s Bash tool covers creating the repository and opening the first pull request without loading any MCP tool definitions into context. Add the GitHub MCP server when the agent must read Actions logs or review threads. Other options are in database MCP servers.

A project skill turns your team’s “add a resource” routine into one command. Save it as .claude/skills/new-resource/SKILL.md:

---
name: new-resource
description: Scaffold a CRUD resource with route, service, schema and tests
---
Create the resource $ARGUMENTS following CLAUDE.md:
1. src/routes/$ARGUMENTS.ts, thin, calling the service only
2. src/services/$ARGUMENTS.service.ts with the business logic
3. src/schemas/$ARGUMENTS.schema.ts with Zod request and response schemas
4. src/services/$ARGUMENTS.service.test.ts covering 401, 404, 422 and the happy path
5. Run ./scripts/verify.sh and report the result

Run it with /new-resource notifications. For skills other people publish, see installing and managing skills.

When the repository already exists, skip the scaffold and start with /init. To get an interactive flow, set CLAUDE_CODE_NEW_INIT=1 before you run /init (checked on Claude Code 2.1.283): Claude then asks which artifacts to set up (CLAUDE.md files, skills, hooks), explores with a subagent, asks follow-up questions, and shows a reviewable proposal before writing anything. If the repository already has an AGENTS.md and no CLAUDE.md, Claude Code v2.1.277 or later on the latest channel reads AGENTS.md as the project instructions (v2.1.281 on Bedrock, Google Cloud, Foundry and LLM gateways; toggle under Project instructions in /config).

Then map the code with codebase analysis. If the real task is moving a legacy app onto a new toolchain, follow the phased approach in database and code migrations.

The output is a generic template. The prompt was underspecified. Add the layout, the conventions and the acceptance checklist, or switch to the generator route so the framework owns the boilerplate.

Dependencies conflict, or a version does not exist. A model’s knowledge of versions lags the registry. Tell Claude to read versions with npm view <pkg> version (or pip index versions, mix hex.info), commit the lockfile, and let verify.sh surface the conflict. Paste the real stderr rather than describing it.

/rewind did not undo the scaffold. Checkpoints do not track files written by Bash commands, so generator and install output survives a rewind. Run git status to see what changed, then git stash -u or git reset --hard to the empty-root or scaffold commit.

The gate is green but proves nothing. Tests that assert nothing, or a /health route that returns 200 without touching the database, pass forever. This is why step 4 breaks an assertion on purpose. Ask for /health to run a SELECT 1, and repeat the break-it check whenever the gate changes.

The Stop hook keeps Claude running. The gate fails for a reason Claude cannot fix, such as Docker not running. Claude Code ends the turn after eight consecutive continuations (CLAUDE_CODE_STOP_HOOK_BLOCK_CAP changes the cap); fix the environment, or remove the hook while you debug the script. If Docker is the cause, check that the hook calls verify-fast.sh, not the full verify.sh.

Claude drifts from early instructions in a long session. An instruction given only in chat, such as “named exports only”, can drop out as context fills. Move it into CLAUDE.md or a path-scoped rule in .claude/rules/; see the memory system guide.

uvx: command not found when the Postgres MCP server starts. Install uv, restart the session, and confirm the server with claude mcp list.

Where to go next after the scaffold passes its gate

Section titled “Where to go next after the scaffold passes its gate”

Using a different tool? The same workflow for other agents is in starting a new project with Cursor and starting a new project with Codex.