ToolAIPilotTAP
Sub

Ad

How I Built a Full Next.js Project Using AI Tools Step by Step: Complete Guide With Code
developerGuideยท 7 min readยท 2,897

How I Built a Full Next.js Project Using AI Tools Step by Step: Complete Guide With Code

A complete Next.js 14 application built using AI tools at every stage from project setup through deployment. This is not a tutorial showing the happy path. It documents the tasks where AI saved hours, the tasks where it caused problems, the prompts that worked, and the exact setup that produced the highest-quality AI output throughout the build. Every code block is from the actual project.

๐Ÿ”ง Tools mentioned in this article
Cursor

Cursor

AI-first code editor used for all component creation, API routes, and multi-file features in this project

cursor.com

Visit
Claude

Claude

Used for architecture planning, database schema design, and code review across the project

claude.ai

Visit
Vercel

Vercel

Deployment platform for Next.js with AI-assisted configuration through the Vercel dashboard

vercel.com

Visit
Marcus Webb

Marcus Webb

June 19, 2026

#build nextjs project with ai tools step by step 2026#how to build next.js app using ai complete guide honest#use ai for coding project nextjs complete honest 2026#nextjs ai development guide step by step working code 2026#build project with ai cursor claude nextjs honest 2026

Quick Answer: A Next.js 14 project with App Router, TypeScript, Prisma, and NextAuth built in three weeks using Cursor with Claude as the primary AI. AI assistance saved approximately 31 hours compared to the manual estimate for the same scope. The biggest savings were in boilerplate setup, type generation, and repetitive CRUD operations. The biggest problems were in authentication edge cases and database relation complexity where AI-generated code required significant debugging. Every major step has working code and notes on where the AI help was real versus where it caused detours.

Project Scope and Stack

  • Project type: task management application with teams, projects, and assigned tasks
  • Stack: Next.js 14 App Router, TypeScript, Prisma ORM, PostgreSQL, NextAuth.js, Tailwind CSS, shadcn/ui
  • Deployment: Vercel with PlanetScale for database
  • Total build time: 22 days across 3 weeks
  • AI-assisted hours tracked: 47 of the total 78 hours
  • Estimated time saving from AI assistance: 31 hours based on manual estimates for same tasks

Step 1: Project Setup and Architecture Planning (Day 1)

bash
# Project initialization โ€” standard Next.js setup
# AI was used for architecture decisions AFTER this step, not during
npx create-next-app@latest task-app \
  --typescript \
  --tailwind \
  --app \
  --src-dir \
  --import-alias '@/*'

cd task-app

# Add Prisma
npm install prisma @prisma/client
npx prisma init

# Add NextAuth
npm install next-auth @auth/prisma-adapter

# Add shadcn/ui
npx shadcn-ui@latest init

Architecture planning was done with Claude before writing any code. The prompt described the feature requirements and asked for a folder structure recommendation with reasoning for each choice. The output was used as a reference document, not copied directly. Two of the five structure suggestions were rejected based on project-specific knowledge Claude did not have.

markdown
# Architecture Planning Prompt Used With Claude
---
Planning a Next.js 14 App Router project for a task management app.
Features: user auth, teams, projects, tasks with assignments and status.

Provide:
1. Recommended folder structure under src/ with reasoning
2. Which data relationships need Prisma relations vs IDs
3. Where to put server actions vs API routes for this use case
4. Auth strategy recommendation: NextAuth sessions vs JWT

Constraints:
- Single developer, so simplicity over scalability
- Deploying to Vercel, database on PlanetScale
- Want to avoid over-engineering at this stage

Do not write any code yet โ€” provide structure and reasoning only.
---

Step 2: Database Schema With Prisma (Day 2)

The Prisma schema was generated with AI assistance using the architecture planning output as context. The generated schema required two revisions: the many-to-many relation between users and teams was missing a role field on the join table, and the task assignment model did not account for the case where a task is assigned to a team rather than an individual. Both gaps were caught by reading the generated schema carefully before running migrations.

prisma
// schema.prisma โ€” final version after AI generation and review
// Two fields were added manually: TeamMember.role and Task.teamId

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider     = "mysql"
  url          = env("DATABASE_URL")
  relationMode = "prisma"
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
  teamMembers   TeamMember[]
  assignedTasks Task[]    @relation("AssignedTasks")
  createdTasks  Task[]    @relation("CreatedTasks")
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
}

model Team {
  id        String       @id @default(cuid())
  name      String
  slug      String       @unique
  members   TeamMember[]
  projects  Project[]
  tasks     Task[]       // tasks assigned to team not individual
  createdAt DateTime     @default(now())
  updatedAt DateTime     @updatedAt
}

model TeamMember {
  id        String   @id @default(cuid())
  userId    String
  teamId    String
  role      String   @default("member") // ADDED MANUALLY โ€” AI missed this
  user      User     @relation(fields: [userId], references: [id])
  team      Team     @relation(fields: [teamId], references: [id])
  createdAt DateTime @default(now())

  @@unique([userId, teamId])
  @@index([userId])
  @@index([teamId])
}

model Project {
  id          String   @id @default(cuid())
  name        String
  description String?
  teamId      String
  team        Team     @relation(fields: [teamId], references: [id])
  tasks       Task[]
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  @@index([teamId])
}

model Task {
  id          String    @id @default(cuid())
  title       String
  description String?
  status      String    @default("todo")
  priority    String    @default("medium")
  projectId   String
  project     Project   @relation(fields: [projectId], references: [id])
  assigneeId  String?
  assignee    User?     @relation("AssignedTasks", fields: [assigneeId], references: [id])
  teamId      String?   // ADDED MANUALLY โ€” for team assignments
  team        Team?     @relation(fields: [teamId], references: [id])
  creatorId   String
  creator     User      @relation("CreatedTasks", fields: [creatorId], references: [id])
  dueDate     DateTime?
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt

  @@index([projectId])
  @@index([assigneeId])
  @@index([teamId])
  @@index([creatorId])
}

Step 3: Server Actions for CRUD Operations (Days 3 to 7)

Server actions were the highest-value AI task in the entire project. Each CRUD operation for tasks, projects, and teams followed the same pattern: get session, validate permission, execute database operation, revalidate path, return result. After the first action was written manually to establish the pattern, every subsequent action was generated by Cursor Composer using the first as context. The acceptance rate on server action generation was 91 percent.

typescript
// src/actions/tasks.ts
// First action written manually to establish pattern
// Subsequent actions AI-generated using this as context reference

'use server'

import { revalidatePath } from 'next/cache'
import { getServerSession }    from 'next-auth'
import { authOptions }         from '@/lib/auth'
import { prisma }              from '@/lib/prisma'
import type { Task }           from '@prisma/client'

type CreateTaskInput = {
  title:       string
  description?: string
  projectId:   string
  assigneeId?: string
  priority?:   string
  dueDate?:    Date
}

export async function createTask(input: CreateTaskInput) {
  const session = await getServerSession(authOptions)
  if (!session?.user?.id) {
    throw new Error('Unauthorized')
  }

  // Verify user has access to the project
  const project = await prisma.project.findFirst({
    where: {
      id:   input.projectId,
      team: { members: { some: { userId: session.user.id } } }
    }
  })

  if (!project) {
    throw new Error('Project not found or access denied')
  }

  const task = await prisma.task.create({
    data: {
      ...input,
      creatorId: session.user.id,
      status:    'todo'
    },
    include: {
      assignee: { select: { id: true, name: true, image: true } },
      creator:  { select: { id: true, name: true, image: true } }
    }
  })

  revalidatePath(`/projects/${input.projectId}`)
  return { success: true, task }
}

export async function updateTaskStatus(
  taskId: string,
  status: 'todo' | 'in_progress' | 'done'
) {
  const session = await getServerSession(authOptions)
  if (!session?.user?.id) throw new Error('Unauthorized')

  // Verify access through project team membership
  const task = await prisma.task.findFirst({
    where: {
      id:      taskId,
      project: { team: { members: { some: { userId: session.user.id } } } }
    },
    include: { project: true }
  })

  if (!task) throw new Error('Task not found or access denied')

  const updated = await prisma.task.update({
    where: { id: taskId },
    data:  { status }
  })

  revalidatePath(`/projects/${task.projectId}`)
  return { success: true, task: updated }
}

Where AI Help Caused Detours

NextAuth configuration was the most problematic AI-assisted area. Three different AI-generated NextAuth configurations failed before a working one was produced. The failures all involved the same pattern: the AI generated configurations that worked for simple email-password auth but did not handle the specific combination of Prisma adapter, multiple OAuth providers, and session strategy correctly. The working configuration was eventually produced by showing Claude the exact error from the console and the exact NextAuth version being used. The lesson was that auth configuration requires the error message context, not just the goal.

Final Thoughts

Building a Next.js project with AI tools in 2026 is significantly faster than building without AI on the categories of work that are pattern-based: schema generation, CRUD server actions, component structure, TypeScript types, and repetitive API routes. The time saving of 31 hours on this project was real and came from those specific areas. The detours in authentication and complex database relations consumed approximately 9 hours โ€” meaning the net saving was roughly 22 hours. Knowing which tasks to hand to AI and which to own manually is the skill that determines whether the net result is positive.

Ad

How I Built a Full Next.js Project Using AI Tools Step by Step: Complete Guide With Code | ToolAIPilot