Step-by-step guide on how to use V0 and Cursor AI to build no-code web apps in minutes.
Building full-stack web applications in 2024 is now possible without writing a single line of code.
You only need two AI-powered programming assistants: one to handle the frontend and the other for the backend.
Here are the tools I recommend for this process:
In this article, I’ll walk you through my personal workflow on how I use these AI programming assistants to quickly build functional and deployable web applications.
Let’s get started.
Head over to v0.dev/chat and sign up for free.
I recommend using your GitHub account for smoother integration, especially if you plan to deploy your apps on Vercel using GitHub integration.
Once you’re in the chat dashboard, you can start describing the web app you’re trying to build.
v0 doesn’t have many customization options, which may appeal to some but could frustrate more advanced engineers who prefer more control.
All the background settings — such as language model and token count — are handled automatically. The only things you can adjust are the theme and the language.
Here’s how I integrate v0 into my workflow:
Let me show you an example.
I’m currently working on a web app that displays a grid of videos on the dashboard with a collapsible left sidebar for navigation.
To help v0 understand what I wanted, I uploaded a screenshot of a similar website as inspiration.
Then I described every detail of the user interface that I want.
Prompt: Using the attached reference image, generate a bento style grid of an AI video generator SaaS with a collapsible left section for the menu. Make sure it’s responsive. The header section includes the user’s name, profile icon, remaining credits, and the app logo and name on the upper left. Make sure to make each thumbnail interactive. When user hovers on the video, it autoplays and the description will be shown on the lower part with black faded background for readability. when user clicks on the video, it expands and shows a bigger video player with the video details on the right side.
You might not get the exact result that you want on the first try, so it’s essential to refine the prompt by describing the changes in the chat field.
In the example above, I was aiming for a masonry-style layout instead of fixed, so I had to do a follow up modification.
Prompt: Looks great! Now can you make sure there are no empty spaces in the grid? revise how you arrange the grid such that they all fit together regardless of the aspect ratios
The design looks good to me. Here’s a snippet of the Typescript code:
import { useState, useEffect, createContext, useContext } from 'react'
import { Menu, ChevronLeft, ChevronRight, Play, Sun, Moon } from 'lucide-react'
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
const ThemeContext = createContext({
theme: 'light',
toggleTheme: () => {},
})
const aspectRatios = [
{ className: 'aspect-square', width: 1, height: 1 },
{ className: 'aspect-video', width: 16, height: 9 },
{ className: 'aspect-[4/3]', width: 4, height: 3 },
{ className: 'aspect-[3/2]', width: 3, height: 2 },
{ className: 'aspect-[3/4]', width: 3, height: 4 }
]
const categories = [
"Music Videos",
"Trailers",
"Commercials",
"Random",
"Top Picks"
]
const generateVideos = (category) => {
return Array(12).fill(null).map((_, index) => {
const aspectRatio = aspectRatios[Math.floor(Math.random() * aspectRatios.length)]
return {
id: `${category}-${index + 1}`,
title: `${category} ${index + 1}`,
description: `This is a ${category.toLowerCase()} video description`,
thumbnail: `/placeholder.svg?height=${aspectRatio.height * 100}&width=${aspectRatio.width * 100}`,
aspectRatio: aspectRatio.className
}
})
}
const videosByCategory = categories.reduce((acc, category) => {
acc[category] = generateVideos(category)
return acc
}, {})
const MasonryGrid = ({ children }) => {
const [columns, setColumns] = useState(4)
useEffect(() => {
const updateColumns = () => {
const width = window.innerWidth
if (width < 640) setColumns(1)
else if (width < 768) setColumns(2)
else if (width < 1024) setColumns(3)
else setColumns(4)
}
updateColumns()
window.addEventListener('resize', updateColumns)
return () => window.removeEventListener('resize', updateColumns)
}, [])
// rest of the code here
}
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light'
setTheme(newTheme)
document.documentElement.classList.toggle('dark')
}
// rest of the code here
}
const ThemeToggle = () => {
const { theme, toggleTheme } = useContext(ThemeContext)
return (
<Button
variant="outline"
size="icon"
onClick={toggleTheme}
className="fixed bottom-4 left-4 z-50"
>
{theme === 'light' ? <Moon className="h-[1.2rem] w-[1.2rem]" /> : <Sun className="h-[1.2rem] w-[1.2rem]" />}
<span className="sr-only">Toggle theme</span>
</Button>
)
}
export default function VideoGenerator() {
const [sidebarOpen, setSidebarOpen] = useState(true)
const [isPlaying, setIsPlaying] = useState({})
const toggleSidebar = () => setSidebarOpen(!sidebarOpen)
const handleVideoHover = (id) => {
setIsPlaying(prev => ({ ...prev, [id]: true }))
}
const handleVideoLeave = (id) => {
setIsPlaying(prev => ({ ...prev, [id]: false }))
}
return (
<ThemeProvider>
// rest of the code here
</ThemeProvider>
)
}
You can also share chat with the public or publish the web app with a unique URL for the selected block. You can unpublish a block at any time.
To integrate the code generated by v0 into my project using Cursor AI, start by creating a file for the page or component.
While you can ask Cursor to create the page for you, I find it’s often better to do it manually since the AI sometimes places files in the wrong directory.
Next, instead of pasting the code directly into a blank file, open Cursor’s composer and ask the AI to integrate the code into your project. This way, Cursor knows which existing elements (like headers and footers) should be included.
Prompt: In the explore page, can you add the header and footer? Also please implement this user interface with shadcn
Here’s the result of the code I generated with v0 integrated into my project:
Pretty cool, right?
I also asked Cursor to use temporary YouTube videos for the thumbnails, which helped me visualize the production environment. Additionally, I requested dark mode support.
I plan to continue improving this interface by adding more features like pagination, more menus, modal video player, etc.
To give you an idea of what’s possible with these two AI tools, take a look at the web app called Flux Labs AI I built and deployed a couple of weeks ago.
Flux Labs
Train Flux image models for your custom images.www.fluxlabs.ai
The app now has thousands of users and just crossed the $500 monthly recurring revenue.
You can learn more about Flux Labs AI in the article below.
Now let’s talk about the pricing of v0 and Cursor AI.
v0 by Vercel offers a free plan which allows you to access and try out generating content for a limited number of messages. If you need to upgrade to a higher message limit, you can upgrade to either of the following subscriptions:
Cursor AI Pricing
One of the great things about Cursor AI is the generous free credits it offers when you sign up. Upon joining, you gain access to Pro features for two weeks, which includes:
These free credits provide ample room to test out all the features and build basic web apps. However, if you’re looking to work on more complex projects, upgrading to a paid tier is recommended:
As much as AI-assisted development tools like v0 by Vercel and Cursor AI have revolutionized how quickly we can build web apps, it’s important to maintain a balanced approach.
AI-generated code can save a lot of time, but it’s far from perfect. These tools are still evolving, and the code they produce often requires a careful review, refinement, and, in some cases, significant rewriting.
I strongly recommend adopting a hybrid workflow. AI can handle the repetitive, boilerplate tasks, while you focus on the more nuanced aspects of development — especially error handling, optimization, and ensuring the code meets your quality standards.
In my experience, I’ve found it’s best to let AI handle the bulk of the coding but always ensure you’re providing clear instructions and thoroughly reviewing the output.
If you’re not an expert on the language or framework, at least take time to analyze the codes and check for possible errors. You can also ask someone with more expertise to review the project before you deploy them.
As someone who has been programming for over a decade, I’ve seen firsthand how development tools have evolved, and the recent shift toward AI-assisted coding is remarkable. Moving from tools like GitHub Copilot to trying out Cursor with Claude 3.5 Sonnet has been an eye-opening experience.
I truly believe this is the future of programming. More and more, my workflow revolves around writing in English — prompting the AI, reviewing its output, and refining the generated code.
The role of a developer is evolving from just writing code to guiding and collaborating with AI.
Software engineer, writer, solopreneur