Skip to content

Starting New Projects from the Terminal

Project initialization with Claude Code is a four-move loop: a specific prompt describing the stack, a scaffold pass over directories, tooling, and configuration, a verification run that proves the scaffold starts, and one course correction. A generated CLAUDE.md carries the conventions into every later session, and /init applies the same workflow to a codebase that already exists.

It is Monday morning and the green light just landed. Your product manager described the service in one sentence — “a REST API for user preferences, PostgreSQL, auth, rate limiting, structured logging” — and the traditional answer is a full day of wiring boilerplate before a line of business logic gets written. Project structure, linter config, database connection, environment variables, CI pipeline: none of it is the product.

Claude Code compresses that day into a single terminal session. The trick is not the generation — any tool can emit a folder tree. The trick is guiding the first prompt so the output is production scaffolding rather than a generic template, then running a tight build-verify-correct loop that catches the gaps while they are still small.

What a ten-minute bootstrap actually gives you

Section titled “What a ten-minute bootstrap actually gives you”
  • A repeatable loop for bootstrapping any project type from the CLI: describe, scaffold, verify, course-correct
  • A tight CLAUDE.md that acts as persistent project memory instead of getting ignored by session three
  • Copy-paste scaffold prompts for Next.js, FastAPI, Phoenix, and Express with Drizzle
  • The /init workflow that turns an unfamiliar existing codebase into a configured session
  • A phased TypeScript migration that keeps the app deployable, and a prototyping flow for when permission prompts are the bottleneck

From an empty directory to a service that runs

Section titled “From an empty directory to a service that runs”

The bootstrap that works is not “type one wish and walk away.” It is four moves: describe with specifics, let Claude scaffold, make it prove the scaffold runs, then correct the one real gap.

  1. Create the project directory and start Claude Code

    Terminal window
    mkdir my-saas-app && cd my-saas-app
    git init
    claude

    Starting with git init matters. Claude Code is git-aware and creates commits at logical checkpoints throughout the scaffolding process. Without a git repository, you lose the ability to rewind when a scaffolding step goes sideways.

  2. Describe the project with enough specificity to avoid generic output

    A vague prompt like “create a web app” gets you a generic template. A specific prompt gets you something you can build on. Include the stack, the primary features, and your conventions.

  3. Make Claude prove the scaffold runs before you build on it

    This is the step that separates a real workflow from a brochure, and it is the one most people skip. Do not trust the tree dump — run it.

    Start Postgres with docker compose, run the migrations, then start the
    dev server and confirm /health returns 200. Run the linter and the test
    suite. Paste any errors and fix them until everything is green.

    Claude is at its best with a real error in front of it. When a dependency version conflicts or a migration fails, the actual stderr is what lets it course-correct precisely instead of guessing.

  4. Course-correct one real gap

    Generated scaffolds almost always miss something specific to how you work. Name it explicitly rather than re-describing the whole project:

    The CRUD handlers call Prisma directly. Extract a preferences service
    layer between the routes and the DB so business logic is testable in
    isolation, and move the Zod schemas into src/schemas/.
  5. Generate the CLAUDE.md file

    This is the step that pays off on every future session, because it is what Claude reads before it reads anything else.

    /init

    The /init command analyzes your project structure, detects frameworks and tooling, and generates a starter CLAUDE.md. Review it and add anything project-specific that Claude cannot infer from the code alone.

Within a few minutes you have a codebase you have actually run: a service layer, validated routes, migrations that applied, a passing test suite, and a Docker setup you watched start — not a tree you are hoping compiles.

Writing a CLAUDE.md that Claude actually follows

Section titled “Writing a CLAUDE.md that Claude actually follows”

The /init command gives you a solid starting point, but the best CLAUDE.md files are pruned hard and refined over time. Here is what to include and what to leave out.

# Build and test commands
npm run dev # Start dev server on port 3000
npm run build # Production build
npm run test # Run vitest
npm run lint # ESLint check
npm run db:migrate # Run Prisma migrations
npm run db:seed # Seed development data
# Code conventions
- Use server components by default, client components only for interactivity
- Named exports only, no default exports except page.tsx and layout.tsx
- Colocate tests next to source files: Button.tsx / Button.test.tsx
- Use Zod for all runtime validation, never trust client input
- Service layer between routes and DB; routes stay thin
# Architecture decisions
- Auth: NextAuth.js with database sessions (not JWT)
- State: Server state via React Server Components, client state via Zustand only where needed
- API: Server Actions for mutations, Route Handlers only for webhooks
# Common gotchas
- Prisma client must be instantiated as singleton (see src/lib/db.ts)
- Middleware runs on Edge Runtime -- no Node.js APIs available
- Migrations are append-only; use the generator, never hand-edit
- IMPORTANT: Never commit .env files. Use .env.example for templates.

Do not include things Claude can figure out by reading your code: standard TypeScript conventions, how React hooks work, or what npm install does. Do not include documentation that changes frequently — link to it instead.

Scaffold prompts for the stacks you start most

Section titled “Scaffold prompts for the stacks you start most”

Each of these is the same shape as the Next.js prompt above — stack, directory layout, conventions, and a first resource to build against — with the details swapped.

This is the prompt for the user-preferences service from the opening. It goes further than the Next.js one in two places: it names the auth, rate-limiting, and logging middleware explicitly, and it asks for the CI workflow in the same pass, so the repository arrives with a green pipeline rather than one you bolt on later.

Config that refuses to boot on a bad value

Section titled “Config that refuses to boot on a bad value”

A scaffold that emits config files is not done. What you want is config that fails loudly on a bad value — and you want to watch it fail. Ask for environment-aware config with startup validation, then test the validation by feeding it something broken.

The “then prove it” half is the point. Config validation you have never seen reject anything is config validation you do not actually have.

Running /init on a codebase you just joined

Section titled “Running /init on a codebase you just joined”

Not every project starts from scratch. When you join an existing codebase, /init becomes your onboarding tool.

  1. Navigate to the project root and run Claude Code

    Terminal window
    cd /path/to/existing-project
    claude
  2. Generate CLAUDE.md from the existing codebase

    /init

    Claude reads your package.json (or equivalent), examines your directory structure, detects test frameworks, and generates a CLAUDE.md tailored to the project.

  3. Ask Claude to fill in what /init missed

    Read through the README, the CI configuration, and the last 20 commits.
    Update CLAUDE.md with any conventions, gotchas, or workflow patterns
    you can identify that aren't already captured.
  4. Validate by asking a question only a well-configured session could answer

    How do I run just the unit tests for the auth module?
    What is the deployment process?

    If Claude answers correctly from CLAUDE.md without reading additional files, your configuration is working.

Migrating a legacy app instead of scaffolding a new one

Section titled “Migrating a legacy app instead of scaffolding a new one”

Sometimes the project you are initializing already exists and the real task is getting it onto a modern toolchain — a legacy Express app that needs TypeScript without a risky big-bang rewrite. The loop is the same describe-generate-verify pattern, applied one phase at a time so the app stays deployable at every step.

  1. Get a phased plan, not a diff

    Analyze this Express app and propose a phased migration to TypeScript
    strict that keeps the service deployable after each phase. Start with
    tsconfig + build wiring and the leaf modules with no internal imports.
  2. Execute phase one and confirm the build still ships

    Implement phase 1: add the TypeScript config and convert the leaf
    modules. Then run the build and the existing test suite and confirm
    both pass before we touch anything else.
  3. Iterate, verifying each phase

    Tests pass. Convert the next layer (the route handlers), add types for
    the external deps they use, and run the suite again. Stop if anything
    breaks.

The discipline is the verify step between phases. Skipping it is how a “gradual” migration quietly accumulates a hundred type errors you discover all at once.

Prototyping when permission prompts are the bottleneck

Section titled “Prototyping when permission prompts are the bottleneck”

Hackathon rules are different. The idea needs validating in hours, and an approval prompt on every file write is the thing slowing you down. There is no “YOLO mode” in Claude Code — the real mechanism is the --dangerously-skip-permissions flag (or the bypassPermissions permission mode), which skips the approval prompts for the session.

Terminal window
claude --dangerously-skip-permissions

Then give it a scope-limited build prompt:

Hooks that enforce what CLAUDE.md only suggests

Section titled “Hooks that enforce what CLAUDE.md only suggests”

Hooks are scripts that run automatically at specific points in Claude’s workflow. CLAUDE.md instructions are advisory; hooks execute deterministically every time.

.claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx eslint --fix"
}
]
}
]
}
}

This hook runs ESLint with auto-fix after every file edit Claude makes. No more reviewing code and finding style issues that should have been caught automatically.

The shape matters here. A matcher entry wraps an inner hooks array of { type: "command", command: ... } objects — there is no bare top-level command key. Hooks do not receive a $FILE_PATH variable either; Claude Code pipes the event as JSON on stdin, so you extract the edited path with jq -r '.tool_input.file_path' and pass it on with xargs. Skip the jq step and ESLint runs with an empty argument and silently does nothing.

Extending setup with skills and MCP servers

Section titled “Extending setup with skills and MCP servers”

Two extensibility mechanisms cut real time off setup, and they solve different problems: a skill is a reusable recipe, an MCP server is a live connection to a system.

A skill that scaffolds features your team’s way

Section titled “A skill that scaffolds features your team’s way”

Once the project is set up, encode the team-specific workflow as a skill that anyone can invoke.

.claude/skills/new-feature/SKILL.md
---
name: new-feature
description: Scaffold a new feature with all required files
---
Create a new feature: $ARGUMENTS
1. Create a new branch named feature/$ARGUMENTS
2. Add route handler in src/app/api/$ARGUMENTS/route.ts
3. Add service in src/services/$ARGUMENTS.service.ts
4. Add Zod schemas in src/schemas/$ARGUMENTS.schema.ts
5. Add tests in src/services/$ARGUMENTS.service.test.ts
6. Update CLAUDE.md if new conventions are introduced

Invoke it with /new-feature user-preferences and Claude scaffolds the entire feature structure following your team’s conventions. For capabilities someone else already wrote, browse skills.sh and install with the universal CLI — npx skills add <owner/repo> — which works across Claude Code, Cursor, and Codex.

Reach for an MCP server when you want a live, stateful tool connection rather than a one-shot recipe.

  • The Postgres MCP server lets Claude introspect your live schema instead of guessing column names while it writes migrations and queries:

    Terminal window
    claude mcp add --transport stdio postgres -- npx -y @modelcontextprotocol/server-postgres "$DATABASE_URL"
  • The GitHub MCP server (@modelcontextprotocol/server-github) lets the same session create the repository, push the scaffold, and open the first PR without leaving the terminal.

Claude generates a generic template instead of what you described. The prompt was too vague. Add specific framework versions, the exact directory layout, and your conventions. The specificity you front-load is the course-correcting you avoid later.

The generated project has dependency conflicts. Claude sometimes pulls incompatible package versions. This is exactly why the verify step is non-negotiable — “run the dev server and fix any errors” puts the real stderr in front of Claude, and it resolves conflicts well when it can see the actual failure.

The scaffold drifts from your prompt over a long session. As context fills, Claude can forget an early instruction such as “named exports only.” Move the rule into CLAUDE.md so it persists, rather than repeating it in chat each time.

CLAUDE.md gets ignored in later sessions. The file is too long or too vague. Cut it under roughly 50 lines and make every line specific and actionable. “Write clean code” earns nothing; “Service layer between routes and DB; routes stay thin” earns its place.

/init misses project conventions. The command analyzes code structure but cannot read your team’s unwritten rules. Always supplement its output with the conventions that live only in people’s heads: branch naming, PR process, deployment procedures. Then validate by asking a question only a well-configured CLAUDE.md could answer.

Where to go next after the project is running

Section titled “Where to go next after the project is running”

The project is scaffolded, the CLAUDE.md is configured, the hooks are in place, and you have watched the dev server start. Next comes navigating code you did not write.