If you already write code every day, Claude Code Boilerplate is not a no-code tool for you. It is a pre-wired Next.js project where every convention -- module structure, DB access, API routes, auth -- is already decided and documented in CLAUDE.md. Claude reads that file before touching any code, which means it generates accurate, consistent output from the first prompt.
This post covers the practical loop: clone, wire conventions, ship a feature.
Clone and set up
git clone https://github.com/your-org/claude-code-boilerplate my-app
cd my-app
npm install
cp .env.example .env # fill in DATABASE_URL, JWT_SECRET, ANTHROPIC_API_KEY
npm run db:push # sync schema to Neon DB
npm run devThat is it. Auth, blog, payments, AI chat, and email are all wired. You are not bootstrapping -- you are extending.
The module convention
Every feature lives in modules/<entity>/ with seven files:
post.schema.ts-- Drizzle table definitionpost.relations.ts-- Drizzle relationspost.types.ts-- TypeScript types (no DB types in UI)post.validation.ts-- Zod schemas for API inputpost.repo.ts-- DB queries only, no business logicpost.service.ts-- Business logic, throws HttpErrorindex.ts-- Public re-exports
This separation matters because it keeps Claude from putting DB queries in components or business logic in routes. When CLAUDE.md says "repo = queries only, service = logic", Claude enforces that rule without reminders.
To add a new entity -- say a comment module -- use the skill:
/drizzle-module commentClaude scaffolds all seven files, registers the table in db/schema.ts, and adds relations. You review, adjust the schema columns, and run:
npm run db:generate # generate SQL migration
npm run db:migrate # apply to Neon DBAdding an API route
Once your module exists, add endpoints with the nextjs-api-route skill:
/nextjs-api-route commentClaude generates app/api/comments/route.ts (list + create) and app/api/comments/[id]/route.ts (get, update, delete). Each route is thin:
// app/api/comments/route.ts
export async function POST(req: Request) {
const user = await getUserFromRequest(req);
const body = await req.json();
const parsed = createCommentSchema.safeParse(body);
if (!parsed.success) return handleError(new HttpError(400, parsed.error.message));
const comment = await commentService.create({ ...parsed.data, authorId: user.id });
return NextResponse.json(comment, { status: 201 });
}Validate, call service, respond. No logic in the route.
The daily loop
Here is what shipping a feature looks like in practice:
1. Describe the schema change in plain English.
"Add a views integer column (default 0) to the post table."
Claude edits post.schema.ts, you run npm run db:generate && npm run db:migrate.
2. Ask for the service method.
"Add incrementViews(postId) to postService."
Claude adds the method to post.service.ts and the query to post.repo.ts, following the existing pattern.
3. Wire the route.
"Add a POST /api/posts/[id]/view route that calls postService.incrementViews."
Claude creates the file. The route is thin, auth-protected if needed.
4. Build the UI.
"Show a view count badge on the blog post header. Increment on page load."
Claude adds a Server Component fetch for the initial count and a useEffect for the increment call.
Each step takes one prompt because CLAUDE.md has already defined where each piece of code goes.
CLAUDE.md as the multiplier
CLAUDE.md is not documentation for humans -- it is context for Claude. The file ships with:
- Folder structure with annotations
- Module conventions (7-file pattern)
- Anti-patterns ("never put DB queries in components")
- Available commands
- Environment variable names
- Skills list
When you add your own convention -- say a specific way to handle multi-tenant queries -- add it to CLAUDE.md. Claude will follow it in every subsequent prompt without you repeating it.
To update CLAUDE.md for a new pattern:
Add a section to CLAUDE.md describing how we handle org-scoped queries:
all repo methods that touch tenant data must accept an orgId parameter
and include it in the WHERE clause.
Now every future findAll Claude writes will include orgId filtering by default.
Skills worth knowing on day one
| Skill | What it does |
|---|---|
/drizzle-module <name> |
Scaffold a full module (7 files) |
/nextjs-api-route <name> |
Generate CRUD routes for a module |
/generate-post <title> |
Write and publish a blog post via API |
/claude-feature |
Add an AI chat or agent endpoint |
/email-setup |
Wire Resend + react-email templates |
/vercel-deploy |
Connect to Vercel and deploy |
Skills are stored in .claude/commands/. You can read any of them to understand what Claude will do before running it, or copy one as a starting point for your own skill.
Concrete next step
Open CLAUDE.md, read the Anti-Patterns section, then run /drizzle-module for the first entity you need to add. The scaffolded files and the conventions in CLAUDE.md together give Claude enough context to build the entire feature loop -- schema, repo, service, routes, UI -- with minimal back-and-forth.
The existing post "How to build your product idea without writing code -- Claude Code Boilerplate walkthrough" covers the product-level overview. This post is the hands-on complement for developers who want to understand the conventions that make that workflow reliable.