Why a Checklist?
Every experienced developer has been burned by the same categories of problems: no error monitoring until production crashes, no backups until data is lost, no rate limiting until someone hammers the API. A checklist externalizes that experience so you don't rely on memory.
This is mine — adapted over several real projects.
Phase 1: Project Setup
Repository
- Initialize Git, set up
.gitignore(usegitignore.iofor your stack) - Add a
README.mdwith: what the project is, how to run it locally, environment variables needed - Protect the
mainbranch — require PRs, disable direct push - Set up Conventional Commits + Husky pre-commit hooks
Environment
- Create
.env.examplewith all required keys (no values) — commit this - Add
.env.localto.gitignore— never commit this - Document each env variable: what it is, where to get it
Code Quality
- ESLint with project-appropriate rules
- Prettier with a
.prettierrcso formatting is never a discussion - TypeScript strict mode (
"strict": truein tsconfig) - Path aliases (
@/) configured in tsconfig and Next.js config
Phase 2: Architecture Decisions
Document these early. Changing them later is expensive.
Data layer
- Which database? (Relational vs document — see my post on MongoDB vs SQL)
- ORM or query builder? (Prisma, Drizzle, Mongoose, raw SQL)
- Where does data fetching live? (Server Components, API routes, separate backend)
Auth strategy
- No auth, or auth? (Don't add it if you don't need it yet)
- Sessions (NextAuth) or JWTs?
- Which OAuth providers?
- Do you need role-based access control?
State management
- Server state: React Query / SWR / native
fetchin Server Components - Client state:
useState/useReducer/ Zustand — pick based on complexity, not habit
File storage
- Where do user-uploaded files go? (Cloudflare R2, AWS S3, Vercel Blob)
- What's the max file size? What types are allowed?
Phase 3: Core Infrastructure
Error handling
- Global error boundary in the React tree
- Centralized API error handler (see my REST API post)
- Error monitoring service connected (Sentry is my default — free tier is generous)
- All async functions have try/catch or .catch()
Logging
- Structured logging in production (JSON format, not console.log)
- Log levels: debug for development, info/warn/error for production
- Request logging middleware (morgan or a custom solution)
- Never log sensitive data (passwords, tokens, PII)
Security
-
helmet()middleware on all API routes - CORS configured with an explicit allowlist, not
* - Rate limiting on auth endpoints (at minimum)
- Input validation on every API endpoint (Zod)
- Parameterized queries — no string concatenation with user input
- Dependencies audited:
pnpm audit
Performance
- Images served through
next/imageor a CDN - Database queries have indexes on frequently-filtered columns
- Heavy routes are code-split (
next/dynamic) - API responses include appropriate cache headers
Phase 4: SEO and Metadata
-
<title>and<meta name="description">on every page - Open Graph tags (
og:title,og:description,og:image) for social sharing -
robots.txt— allow or block crawlers as needed -
sitemap.xml— auto-generated from your routes - Canonical URLs to prevent duplicate content penalties
- Structured data (JSON-LD) for entities that benefit from rich snippets (articles, products, local business)
Phase 5: Before Going Live
Testing
- Critical user paths manually tested: sign up, sign in, core feature, sign out
- Test on mobile (actually on a device, not just browser resize)
- Test with slow network (Chrome DevTools → Network → "Slow 3G")
- Test with JavaScript disabled (if SEO matters)
Infrastructure
- Environment variables set on the hosting platform — not hardcoded
- Database backups scheduled and tested (restore once, not just export)
- Deployment process documented: how do you release a new version?
- Domain, SSL certificate, DNS records verified
Monitoring
- Uptime monitoring (Better Uptime, UptimeRobot — both have free tiers)
- Error monitoring alerting to email or Slack
- Core Web Vitals baseline measured (Google PageSpeed Insights)
Phase 6: After Launch
The work doesn't stop at deployment.
- Set a calendar reminder to audit dependencies monthly
- Review error logs weekly for the first month
- Monitor server costs — serverless functions can surprise you
- Collect user feedback early, even informally
The Real Lesson
No project ships with this checklist 100% complete — and that's fine. The value is knowing which boxes you've consciously skipped and why. "We don't have rate limiting yet because we have zero users" is a valid decision. "We didn't know we needed rate limiting" is how you get into trouble.
