I’ve got a graveyard of unfinished side projects. You probably do too. A habit tracker that never got past the database schema. A bookmark manager that lived as a half-built API for six months. A portfolio site I redesigned three times and never deployed.
The ideas weren’t the problem. I had plenty of those. The bottleneck was always the boring stuff. Setting up auth. Writing CRUD endpoints. Building form components for the tenth time. By the time I got through the boilerplate, I’d lost all motivation for the actual product.
That changed when I started using Claude Code. Not because it writes perfect code — it doesn’t. But because it handles the parts that drain my energy, so I actually finish things.
Here’s my exact process.
Phase 1: Project Scaffolding
I used to spend half a Saturday just getting a project set up. Install dependencies, configure Tailwind, set up Prisma, wire up auth, create the folder structure. It’s not hard work, but it’s tedious. And tedious work kills momentum.
Now I open my terminal and type something like this:
claude "Set up a new Next.js 14 project with TypeScript, Tailwind CSS, Prisma with PostgreSQL, and NextAuth with GitHub provider. Use the app router. Create a basic layout with a navbar and a main content area."
That’s it. In a couple of minutes, I’ve got a working foundation. Not a perfect one — I’ll tweak things later. But it compiles, it runs, and I can start building on top of it immediately.
The key is being specific. Don’t just say “set up a Next.js project.” Tell it which packages, which auth provider, which CSS approach. The more specific your prompt, the less cleanup you do after.
Phase 2: Database Schema
This is where I used to overthink everything. Should I normalize this? Do I need a junction table? What about soft deletes? I’d spend hours on a schema for a side project that might have ten users.
Now I describe what I need in plain English:
claude "Create a Prisma schema for a link shortener. I need users, links, and click events. Users have many links. Each link has an original URL, a short code, a title, and a click count. Click events track the timestamp, referrer, and country. Add createdAt and updatedAt to everything."
Done. It generates the schema, the relations are correct, and I can run prisma migrate right away. If something looks off, I tell it to fix it. “Make the short code unique and add an index on it.” Takes seconds.
I’ve learned to not overthink the schema on side projects. Get something working first. You can always migrate later. Claude Code makes this mindset easier because the cost of generating a schema is basically zero.
Phase 3: API Routes
Writing CRUD endpoints is the definition of boring work. It’s the same pattern every time: validate input, check auth, query database, handle errors, return response. I’ve written this code hundreds of times.
Here’s what I do now:
claude "Create API routes for links: GET /api/links (list all for current user), POST /api/links (create new), GET /api/links/[id] (get one), PUT /api/links/[id] (update), DELETE /api/links/[id] (delete). Use NextAuth for auth. Validate inputs with zod. Return proper error codes."
It generates all five routes with validation, auth checks, and error handling. The stuff that would take me a couple of hours manually — done in minutes.
I still read through every route. Sometimes the error handling is too generic, or it misses an edge case. But fixing a few lines is way faster than writing everything from scratch.
Phase 4: UI Components
I’m not a designer. I can make things look decent with Tailwind, but building a dashboard layout from scratch takes me forever. I fiddle with spacing, I can’t decide on a grid layout, I forget how flexbox gaps work for the third time this month.
claude "Build a dashboard page at /dashboard that shows all of the current user's links in a card grid. Each card shows the title, short URL, click count, and a copy button. Add a 'Create New Link' button in the top right. Use Tailwind for styling. Make it responsive — single column on mobile, three columns on desktop."
The result isn’t going to win design awards. But it’s functional, it’s clean, and I can iterate on it. That’s all I need from a first pass.
Here’s a trick I’ve learned: ask for the component and the data fetching separately. If you ask for everything at once, the component gets messy. I usually do:
claude "Create a server component at app/dashboard/page.tsx that fetches all links for the current user and passes them to a LinkGrid client component."
Then:
claude "Create the LinkGrid client component that takes an array of links and renders them as cards. Include a copy-to-clipboard button for each short URL."
Small, focused prompts. Always.
Phase 5: Polish
This is the phase that separates shipped projects from abandoned ones. Loading states, error boundaries, empty states, toast notifications — the stuff that makes an app feel real instead of a prototype.
I used to skip all of this on side projects. Not because I didn’t know how, but because I was already exhausted from the first four phases.
Now it’s easy:
claude "Add loading states to the dashboard — show skeleton cards while links are loading. Add an empty state when the user has no links yet with a message and a CTA to create their first link. Add error handling that shows a toast notification if link creation fails."
This is the phase where Claude Code gives me the biggest win. Not because the code is complex — it’s not. But because I actually do it now. Before, I’d ship without loading states and tell myself I’d add them later. I never did.
Real Example: LinkSnap
Let me walk you through an actual project. I built a link shortener called LinkSnap in one evening. Not a weekend. An evening.
6:30 PM — Scaffolding. Next.js, Tailwind, Prisma, NextAuth with GitHub. One prompt. Working app in minutes.
6:45 PM — Database schema. Users, links, click tracking. Another prompt. Ran the migration.
7:00 PM — API routes. Full CRUD for links, plus a redirect endpoint that logs clicks. Two prompts because I wanted the redirect logic separate.
7:30 PM — Dashboard UI. Link cards, create form, copy buttons. Three prompts — page layout, link grid, create modal.
8:15 PM — Polish. Loading skeletons, empty states, toast notifications, a simple analytics view showing clicks per day.
8:45 PM — Deployed to Vercel. Connected a custom domain. Done.
The whole thing took about two hours of actual work. I spent maybe another 30 minutes manually tweaking things — adjusting the auth callback URL, fixing a z-index issue on the modal, and changing some copy.
A year ago, this would’ve been a weekend project. And honestly, I probably would’ve abandoned it on Sunday afternoon when I realized I still needed to build the analytics page.
What I’ve Learned About Prompting
The single biggest lesson: break everything into small, clear prompts. Don’t ask Claude Code to “build me a link shortener.” You’ll get a mess.
Instead, think of it like delegating to a junior developer. You wouldn’t say “build the whole feature.” You’d say “create the database table, then build the API, then build the UI.” Same thing here.
Here’s what works:
- One concern per prompt. Database schema is one prompt. API routes are another. UI is another.
- Be specific about tech choices. “Use zod for validation” not “add validation.”
- Reference existing code. “Follow the same pattern as the links API” saves time and keeps things consistent.
- Tell it what NOT to do. “Don’t add pagination yet, just fetch all records” prevents over-engineering.
Here’s what doesn’t work:
- Vague prompts like “make it better” or “improve the code.”
- Asking for too much at once. If your prompt is a paragraph long, split it up.
- Expecting it to make product decisions. It’ll build what you ask for, but you need to decide what to build.
When to Intervene
Claude Code is great at the mechanical stuff. It’s not great at everything. I’ve learned to step in for:
Complex state management. If your app has tricky client-side state with lots of interdependencies, write that yourself. The AI tends to create state shapes that get awkward fast.
Auth flows. The basic setup is fine, but anything involving role-based access, refresh tokens, or multi-tenant auth — I write that manually. Too many edge cases.
Payment integration. Stripe is well-documented enough that Claude can generate basic checkout flows, but I don’t trust generated code with money. I write payment logic by hand and test every edge case.
Business logic. The stuff that makes your app unique. If it’s the core value proposition, write it yourself. You need to understand it deeply because you’ll be debugging it later.
My rule of thumb: if it’s the same in every project, let Claude do it. If it’s unique to your project, do it yourself.
The Time Math
Here’s a rough comparison for a typical side project:
Without Claude Code:
- Scaffolding: 2-3 hours
- Database + migrations: 1-2 hours
- API routes: 3-4 hours
- UI components: 4-6 hours
- Polish: 2-3 hours (if I even get to it)
- Total: 12-18 hours across a weekend or two
With Claude Code:
- Scaffolding: 10 minutes
- Database + migrations: 15 minutes
- API routes: 30 minutes
- UI components: 1 hour
- Polish: 30 minutes
- Manual tweaks and fixes: 1 hour
- Total: 2-3 hours in one evening
That’s not 10x on every single task. Some things only save a little time. But the compounding effect is massive. And the biggest gain isn’t even the time — it’s the momentum. When you can see your idea running in a browser after an hour, you don’t want to stop. When you’re still writing database migrations after three hours, you want to close your laptop and watch TV.
It Didn’t Make Me Lazy
I know what some people are thinking. “You’re not really building anything. The AI is doing all the work.”
I disagree. I’m making every product decision. I’m deciding what to build, how it should work, what the data model looks like, and how the pieces fit together. I’m reviewing every line of generated code. I’m debugging the parts that don’t work right.
What I’m NOT doing is typing out boilerplate for the hundredth time. And I don’t miss it.
Claude Code didn’t make me a worse developer. It made me a developer who finishes things. I shipped three side projects in the last two months. In the year before that, I shipped zero.
Finishing is the hardest part of side projects. Not the architecture, not the code quality, not the tech stack. Just getting it done and putting it out there. Anything that helps me cross that line is worth using.