Project Initialization
Choose a stack, scaffold the directory, and make the first green build.
Why
The first hour of a project sets the cost of every future change. A scaffold that already has a build, a test runner, and a deploy target means new code is testable and shippable from commit one. Teams that start with an empty folder and ad-hoc files spend weeks retro-fitting CI, lint, and env loading — by then the habits are baked in. A good initializer also encodes team conventions (naming, layering, error handling) so every project starts from the same baseline rather than each dev's personal preference.
When
Day 0, before any feature code. Takes 30-60 min if you use a generator. Skip only for throwaway prototypes you will delete within 24 h.
How
1. Pick the stack from your ADR (do NOT re-debate here) - Read docs/adr/0001-tech-stack.md; if it doesn't exist, write it first 2. Run the official generator, not a random GitHub template - Next.js: npx create-next-app@latest --ts --eslint --tailwind --app - Vite+React: npm create vite@latest my-app -- --template react-ts - NestJS: npx @nestjs/cli new my-api --package-manager pnpm - Accept the defaults; diverge later, not now 3. Verify the three green lights before writing any feature - npm run build → exits 0 - npm test → passes (even if it's a placeholder test) - npm run lint → zero errors 4. Add the missing baseline files the generator skips - .env.example with every var documented (never .env in git) - .editorconfig, .nvmrc / .tool-versions, .dockerignore - README.md with "how to run locally" in 3 commands 5. First commit: the scaffold + a CI workflow that reproduces the 3 green lights - If CI is red on commit 1, the scaffold is broken — fix before any feature
Example
# Next.js + TypeScript + Tailwind, pnpm pnpm create next-app@latest my-saas --ts --eslint --tailwind --app --import-alias "@/*" cd my-saas pnpm dev # → http://localhost:3000 green # Add baseline cat > .env.example <<'EOF' DATABASE_URL=postgresql://user:pass@localhost:5432/db NEXTAUTH_SECRET= # openssl rand -base64 32 EOF echo "20.11.0" > .nvmrc # Verify three greens pnpm build && pnpm test && pnpm lint # all pass git add -A && git commit -m "chore: scaffold next.js + ts + tailwind"
Common Problems
- ⚠Using a 2-year-old template that pins outdated deps — you spend day 1 upgrading instead of building.
- ⚠Skipping the test runner because 'we'll add it later' — later never comes, and untested code piles up.
- ⚠Committing .env with real secrets on commit 1, then having to rotate keys and rewrite git history.
- ⚠Choosing a stack by blog popularity instead of team familiarity — the first bug takes 3x longer to fix.
Best Practices
- ✓Pin the Node/package-manager version in .nvmrc and package.json engines so CI and teammates match exactly.
- ✓Make the first CI workflow fail on any warning, not just errors — it's cheaper to enforce discipline at commit 1 than at commit 500.
- ✓Keep the scaffold commit separate from the first feature commit so revert is surgical.
- ✓Document the 'how to run locally' in README with copy-paste commands, not prose paragraphs.