Setup and context: Eliminating the "Setup Debt" in Every New Project
How much time do you spend on the same setup tasks every time you start a new project?
Configuring package.json, copying tsconfig, setting up ESLint and Prettier, adding Git hooks, building CI/CD pipelines — even experienced developers spend 2–3 hours on this boilerplate. Claude Code can complete all of it in under 10 minutes.
And it doesn't just copy files — it generates configurations dynamically optimized for your project's specific requirements.
This guide walks you through a complete system for automating project initialization with Claude Code, starting with the crucial CLAUDE.md design patterns and moving through scaffolding, Git hook setup, and CI/CD pipelines — all with working code and concrete steps.
Who this is for:
- Intermediate to advanced developers who have been using Claude Code for 1–3 months
- Tech leads struggling to standardize development environments across a team
- Solo developers who want to ship faster on new projects
1. CLAUDE.md Design Principles and Complete Templates
CLAUDE.md is Claude Code's "project blueprint." A well-designed CLAUDE.md serves as a north star that enables the AI to autonomously generate high-quality code.
1-1. Three Principles for an Effective CLAUDE.md
Principle 1: Be Specific — Describe "How," Not Just "What"
Weak example:
# Tech Stack
- Next.js
- TypeScript
- Tailwind CSS
Strong example:
# Tech Stack & Implementation Rules
- Next.js 15 (App Router) — use src/app/ directory. pages/ directory is forbidden
- TypeScript strict mode — do not modify "strict": true in tsconfig.json
- Tailwind CSS — no inline styles or CSS Modules. Tailwind utility classes only
Principle 2: State Prohibitions Explicitly
Claude Code will fall back to common conventions unless told otherwise. If there are specific libraries or patterns you want to avoid, state them explicitly.
Principle 3: Use a Context Hierarchy
For large projects, put global rules in the root CLAUDE.md and directory-specific rules in subdirectory files:
project/
├── CLAUDE.md ← Global rules (project-wide)
├── src/
│ ├── CLAUDE.md ← Frontend-specific rules
│ └── api/
│ └── CLAUDE.md ← API-specific rules
└── tests/
└── CLAUDE.md ← Testing conventions
1-2. Project-Type CLAUDE.md Templates
Here are battle-tested templates you can customize for your projects.
① Next.js Web Application Template
# [Project Name] — CLAUDE.md
## Overview
[One-sentence description of what this project does]
## Tech Stack
- Next.js 15 (App Router) + TypeScript strict
- Tailwind CSS + shadcn/ui
- Prisma + PostgreSQL (Supabase)
- Vitest (unit tests) + Playwright (E2E tests)
- Vercel deployment
## Directory Structure
src/
├── app/ ← Next.js App Router
├── components/ ← Shared UI components
│ ├── ui/ ← shadcn/ui components (do not edit directly)
│ └── features/ ← Feature-specific components
├── lib/ ← Utilities and helpers
├── hooks/ ← Custom hooks
└── types/ ← Type definitions
## Coding Conventions
- Components: PascalCase, use `function` keyword (no arrow functions)
- Variables and functions: camelCase
- Type definitions: prefer `interface` over `type` (use `type` for unions only)
- Import order: Node.js → external libraries → internal (use `@/` alias)
- Data fetching: Server Components only (no fetch in Client Components)
## Git Conventions
- Branches: use `feat/`, `fix/`, `docs/`, `refactor/`, `test/` prefixes
- Commit messages: `feat: description` format (English)
- PRs: always target `main`, self-review before merging
## Prohibited Patterns
- `any` type (use `unknown` instead)
- `console.log` in production code (use the `logger` utility)
- Creating a `pages/` directory
- Inline styles (`style={{}}` attributes)
- Data fetching in Client Components② Node.js/Express API Server Template
# [API Name] — CLAUDE.md
## Overview
[RESTful / GraphQL API description]
## Tech Stack
- Node.js 22 + TypeScript strict
- Express 5 + Zod (validation)
- Prisma + PostgreSQL
- Jest (tests) + Supertest (integration tests)
- pino (logging)
## API Design Principles
- RESTful: resource names in plural form (/users, /posts)
- Response shape: `{ data: T, meta?: PaginationMeta, error?: ApiError }`
- Error handling: always return appropriate HTTP status codes
- Validation: use Zod schemas at every endpoint
## Security Requirements
- Apply auth middleware to all endpoints (explicitly exclude public routes)
- Rate limiting: apply uniformly under /api/
- CORS: manage allowed origins via environment variables
## Prohibited Patterns
- Direct process.env access (use config/env.ts)
- Using req.body without type assertions
- Multi-table updates without transactions2. Scaffolding Automation with Claude Code
With CLAUDE.md in place, you're ready to auto-generate the project structure.
2-1. Interactive Scaffolding Prompt
Pass the following prompt to Claude Code to interactively generate your project structure:
claudePlease initialize a Next.js project with the following specifications.
## Project Specs
- Project name: my-saas-app
- Features: user auth + subscription management + dashboard
- Database: PostgreSQL (Supabase)
- Auth: NextAuth.js v5
- Payments: Stripe
## What to Do
1. Create package.json with the necessary dependencies
2. Configure tsconfig.json in strict mode
3. Create the src/ directory structure with .gitkeep in each directory
4. Create a .env.example with the required environment variables
5. Create ESLint + Prettier config files
6. Generate CLAUDE.md based on the requirements above
7. Add comments explaining the purpose of each file
Use parallel Sub-agents to maximize efficiency.
2-2. Sub-agent Parallel Execution Pattern
Claude Code can run multiple sub-agents in parallel. For project initialization, this pattern works well:
Please run the following tasks in parallel using Sub-agents:
Agent 1: Frontend setup
- Create the src/components/ directory structure
- Generate initial shadcn/ui components (Button, Card, Input)
- Optimize globals.css and Tailwind config
Agent 2: Backend setup
- Create src/lib/db.ts (Prisma client)
- Create src/lib/auth.ts (NextAuth.js config)
- Define the initial Prisma schema (User, Session tables)
Agent 3: Config files
- Optimize .eslintrc.json
- Create prettier.config.js
- Optimize .gitignore (Next.js + Prisma)
When all agents are done, verify consistency across files.
This splits the work across three simultaneous agents, completing initialization roughly 3× faster.
For a deep dive into Sub-agent patterns, check out Mastering Parallel Agent Development in Claude Code.
2-3. One-Command Initialization Script
For project templates you use repeatedly, save the workflow as a shell script:
#!/bin/bash
# init-project.sh — Automated project initialization via Claude Code
set -euo pipefail
PROJECT_NAME="${1:-my-new-project}"
PROJECT_TYPE="${2:-nextjs}" # nextjs | express | library
echo "🚀 Initializing project: ${PROJECT_NAME} (${PROJECT_TYPE})"
mkdir -p "${PROJECT_NAME}"
cd "${PROJECT_NAME}"
PROMPT_FILE=$(mktemp /tmp/init_prompt_XXXXXX.txt)
cat > "${PROMPT_FILE}" << EOF
Initialize the project "${PROJECT_NAME}" using the ${PROJECT_TYPE} template.
Requirements:
1. package.json (with TypeScript, ESLint, Prettier, Vitest)
2. tsconfig.json (strict mode)
3. src/ directory structure
4. .env.example (env vars appropriate for the project type)
5. CLAUDE.md (tailored to this project)
6. .github/workflows/ci.yml (GitHub Actions CI)
7. README.md (with setup instructions)
All files should be production-ready quality.
EOF
claude < "${PROMPT_FILE}"
rm -f "${PROMPT_FILE}"
echo "✅ Project initialization complete!"
echo "📁 cd ${PROJECT_NAME} && npm install"chmod +x init-project.sh
./init-project.sh my-saas-app nextjs
./init-project.sh my-api express
./init-project.sh my-npm-lib library3. Automated Git Hook Configuration
Use Claude Code to set up Git hooks that enforce code quality automatically.
3-1. husky + lint-staged Setup
Configure the following Git hooks for this project:
1. pre-commit hook
- Run ESLint + Prettier on staged files only via lint-staged
- Run TypeScript type checking (tsc --noEmit)
- If test files changed, run related tests
2. commit-msg hook
- Enforce Conventional Commits format
- Allowed prefixes: feat, fix, docs, style, refactor, test, chore, ci
3. pre-push hook
- Run the full test suite
- Verify the build succeeds
Configure husky and lint-staged in package.json and create the .husky/ directory.
The package.json snippet Claude Code generates:
{
"scripts": {
"prepare": "husky",
"lint": "eslint src/ --ext .ts,.tsx",
"lint:fix": "eslint src/ --ext .ts,.tsx --fix",
"format": "prettier --write src/",
"type-check": "tsc --noEmit",
"test": "vitest",
"test:run": "vitest run"
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,yml}": [
"prettier --write"
]
}
}3-2. commit-msg Hook Implementation
# .husky/commit-msg (generated by Claude Code)
#!/bin/bash
COMMIT_MSG_FILE="$1"
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
PATTERN="^(feat|fix|docs|style|refactor|test|chore|ci)(\(.+\))?: .{1,72}$"
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "❌ Commit message does not follow Conventional Commits format."
echo ""
echo "Expected: <type>(<scope>): <description>"
echo ""
echo "Examples:"
echo " feat: add user authentication"
echo " fix(auth): resolve session deletion bug on logout"
echo " docs: add setup instructions to README"
echo ""
echo "Allowed types: feat, fix, docs, style, refactor, test, chore, ci"
exit 1
fi
echo "✅ Commit message validated"4. Automated CI/CD Pipeline Construction
4-1. GitHub Actions Workflow Auto-Generation
Set up a GitHub Actions CI/CD pipeline with the following requirements:
## CI workflow (runs on PRs)
- Cross-version testing on Node.js 20 and 22
- Dependency caching (npm cache)
- ESLint + TypeScript type checking
- Vitest unit tests + coverage report
- Playwright E2E tests (headless)
## CD workflow (on merge to main)
- Automatic deployment to Vercel
- Post-deploy smoke tests
Maximize parallelism to minimize pipeline time.
For more on combining CI/CD with Claude Code hooks, see the Claude Code HTTP Hooks × GitHub Actions Integration Guide.
The .github/workflows/ci.yml Claude Code generates:
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint-and-type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm run type-check
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['20', '22']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run test:run -- --coverage
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-${{ matrix.node-version }}
path: coverage/
e2e:
runs-on: ubuntu-latest
needs: [lint-and-type-check, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run build
- run: npm run test:e2e
env:
DATABASE_URL: ${{ secrets.DATABASE_URL_TEST }}4-2. Type-Safe Environment Variable Management
Implement this environment variable management best practice in the project:
1. Create src/config/env.ts with Zod-based validation
2. Sync .env.example with README documentation
3. Configure GitHub Actions secrets integration
Generate a sample env.ts as well.
The generated src/config/env.ts:
import { z } from 'zod'
/**
* Type-safe environment variable validation
* All env vars are defined and validated using Zod schemas
*/
const envSchema = z.object({
// Database
DATABASE_URL: z.string().url('DATABASE_URL must be a valid URL'),
// Auth
NEXTAUTH_SECRET: z.string().min(32, 'NEXTAUTH_SECRET must be at least 32 characters'),
NEXTAUTH_URL: z.string().url(),
// External services
STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
STRIPE_WEBHOOK_SECRET: z.string().startsWith('whsec_'),
// Optional
SENTRY_DSN: z.string().url().optional(),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
})
// Server-side only — referencing from Client Components causes a build error
const parseEnv = () => {
const parsed = envSchema.safeParse(process.env)
if (!parsed.success) {
console.error(
'❌ Environment variable validation failed:',
parsed.error.flatten().fieldErrors
)
throw new Error('Invalid environment configuration. Check your .env.example.')
}
return parsed.data
}
export const env = parseEnv()5. Managing CLAUDE.md Across Multiple Projects
When working on multiple projects simultaneously, centralizing CLAUDE.md management is critical.
5-1. Template Repository Approach
Create a CLAUDE.md template repository with this structure:
templates/
├── base.md ← Shared rules for all projects
├── nextjs.md ← Next.js-specific rules
├── express.md ← Express-specific rules
├── library.md ← npm library rules
└── merge.sh ← Script to merge templates into CLAUDE.md
merge.sh should accept a project type as an argument and combine
base.md + [type].md into a single CLAUDE.md output.
Generated merge.sh:
#!/bin/bash
# CLAUDE.md template merge script
TEMPLATE_DIR="${HOME}/.claude-templates"
PROJECT_TYPE="${1:-nextjs}"
OUTPUT="${2:-CLAUDE.md}"
if [ ! -f "${TEMPLATE_DIR}/${PROJECT_TYPE}.md" ]; then
echo "❌ Template not found: ${PROJECT_TYPE}"
echo "Available: nextjs, express, library"
exit 1
fi
{
cat "${TEMPLATE_DIR}/base.md"
echo ""
echo "---"
echo ""
cat "${TEMPLATE_DIR}/${PROJECT_TYPE}.md"
} > "${OUTPUT}"
echo "✅ Generated ${OUTPUT} (template: ${PROJECT_TYPE})"5-2. Cross-Project CLAUDE.md Sync
#!/bin/bash
# sync-claude-md.sh — Sync shared rules across all projects
TEMPLATE_REPO="${HOME}/.claude-templates"
PROJECTS=(
"${HOME}/projects/project-a"
"${HOME}/projects/project-b"
"${HOME}/projects/project-c"
)
for project in "${PROJECTS[@]}"; do
if [ -f "${project}/CLAUDE.md" ]; then
PROJECT_TYPE=$(grep -m1 "^## Project Type" "${project}/CLAUDE.md" | awk '{print $NF}')
"${TEMPLATE_REPO}/merge.sh" "${PROJECT_TYPE:-nextjs}" "${project}/CLAUDE.md"
echo "✅ Updated CLAUDE.md in ${project}"
fi
done6. Common Errors and Fixes
Error 1: Claude Code Ignores the Directory Structure
Cause: The CLAUDE.md directory definition was too vague, so Claude Code made independent structure decisions.
Fix: Add an explicit constraint to CLAUDE.md.
## Hard Constraints
- The directory structure under src/ is fixed. Creating new directories requires prior confirmation.
- components/ui/ is managed by shadcn/ui. Do not edit directly — use `npx shadcn-ui add`.Error 2: Sub-agents Cause File Conflicts
Cause: Multiple sub-agents tried to edit the same file simultaneously.
Fix: Clearly separate file ownership per agent.
Agent 1: responsible for src/components/ only
Agent 2: responsible for src/lib/ only (do not touch src/lib/components/)
Agent 3: responsible for root-level config files only
Error 3: GitHub Actions Can't Find Environment Variables
Cause: Variables defined in .env.example weren't registered as GitHub Secrets.
Fix: Use Claude Code to debug CI failures.
The GitHub Actions CI is failing. Review the following log,
identify which environment variables are missing, and suggest fixes:
[paste log here]
7. Advanced: AI-Native Development Workflow
With CLAUDE.md and scaffolding in place, integrate Claude Code into your day-to-day development.
For more on multi-agent orchestration, see A Practical Guide to Mastering Claude Code's Multi-Agent Features.
7-1. Standardized Feature Addition Prompt (for CLAUDE.md)
## Feature Addition Workflow
When implementing new features, follow these steps:
1. Add type definitions to src/types/
2. Implement business logic in src/lib/ (with tests)
3. Create UI components in src/components/features/
4. Add pages/API routes to src/app/
5. Add E2E tests to src/tests/e2e/
6. Update the API spec in README
Match the existing code style at each step.7-2. Integrating Automated Code Review
#!/bin/bash
# pre-push-review.sh — Auto code review via Claude Code on push
echo "🔍 Running automated code review with Claude Code..."
CHANGED_FILES=$(git diff --name-only origin/main...HEAD | grep -E "\.(ts|tsx)$")
if [ -z "$CHANGED_FILES" ]; then
echo "No TypeScript files changed. Skipping."
exit 0
fi
claude << EOF
Please code review the following files:
${CHANGED_FILES}
Check for:
- CLAUDE.md rule compliance
- TypeScript type safety
- Security issues
- Performance concerns
- Test coverage
If you find critical issues, halt processing and provide fix suggestions.
EOFSummary
In this guide, we walked through fully automating project initialization with Claude Code:
- CLAUDE.md design: The three principles — specificity, explicit prohibitions, and context hierarchy — sharpen AI accuracy
- Scaffolding: Sub-agent parallel execution cuts initialization time by two-thirds
- Git hooks: husky + lint-staged automatically enforce code quality
- CI/CD: Generate production-ready GitHub Actions workflows with a single prompt
- Multi-project management: Template repositories unify team-wide conventions
With this automation workflow, you can cut project initialization time from 2–3 hours down to under 10 minutes — freeing you to focus on the features that actually matter.