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.
What a verified bootstrap gives you
Section titled “What a verified bootstrap gives you”- 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 aStophook before Claude may declare the work done. - A
CLAUDE.mdunder the vendor’s 200-line target, plus a recorded launch recipe for the bundled/runand/verifyskills. - 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.
| Route | Use it when | What you verify |
|---|---|---|
Claude runs the official generator (create-next-app, mix phx.new), then customizes | The framework has a maintained generator | The diff between the generator output and Claude’s changes, plus the verify script |
| Claude writes the project from scratch | No 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 repository | Your team already has a golden path | Only 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.
-
Create the repository and commit before Claude touches it
Terminal window mkdir prefs-api && cd prefs-apigit initgit commit --allow-empty -m "chore: empty root"claude --permission-mode planThe empty commit matters more than it looks. Claude Code checkpoints do not track files changed by Bash commands, and a generator or
npm installruns through Bash. Esc Esc and/rewindtherefore cannot undo a bad scaffold;gitcan.--permission-mode planstarts the session in plan mode, so Claude explores and proposes without writing files. -
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.
-
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
latestchannel), auto mode is the starting mode for interactive terminal sessions: a classifier reviews each action and only risky ones reach you. On thestablechannel (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" -
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.
-
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 layerbetween routes and db so business logic is testable without HTTP, move theZod schemas to src/schemas/, and run ./scripts/verify.sh again. -
Record the conventions and the launch recipe
/init/initanalyzes the project and writes a startingCLAUDE.mdwith build commands, test instructions and the conventions it detects; if aCLAUDE.mdalready 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/runand/verifyskills 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.
Scaffold prompts for other stacks
Section titled “Scaffold prompts for other stacks”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"underpermissionsin~/.claude/settings.json(user settings); Claude Code ignoresautoandbypassPermissionsasdefaultModein project settings. --dangerously-skip-permissionsonly 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:
claude mcp add postgres -e DATABASE_URI="$DATABASE_URL" -- uvx postgres-mcp --access-mode=restrictedFor 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-resourcedescription: 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 only2. src/services/$ARGUMENTS.service.ts with the business logic3. src/schemas/$ARGUMENTS.schema.ts with Zod request and response schemas4. src/services/$ARGUMENTS.service.test.ts covering 401, 404, 422 and the happy path5. Run ./scripts/verify.sh and report the resultRun it with /new-resource notifications. For skills other people publish, see installing and managing skills.
Joining an existing codebase instead?
Section titled “Joining an existing codebase instead?”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.
When a Claude Code bootstrap goes wrong
Section titled “When a Claude Code bootstrap goes wrong”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.