Lovable - complete guide to the AI app builder
What is Lovable?
Lovable (formerly known as GPT Engineer) is an advanced AI platform for building web applications from text descriptions. Unlike the competition, Lovable stands out with its deep native integration with GitHub and Supabase, offering a professional development workflow from prototype to production.
Lovable lets you not only generate code, but also edit components visually, manage versions through GitHub, and automatically configure a backend with authentication via Supabase - all without leaving the platform.
Why Lovable?
Key advantages
- Native GitHub integration - Automatic commits, branching, PRs
- Supabase out-of-the-box - Authentication, database, storage
- Visual Editor - Edit components without coding
- Professional code - TypeScript, Tailwind, best practices
- Multi-page apps - Routing, dynamic routes, protected pages
- Deploy flexibility - Vercel, Netlify, self-hosting
Lovable vs Bolt vs v0
| Feature | Lovable | Bolt.new | v0 by Vercel |
|---|---|---|---|
| Type | Fullstack apps | Fullstack apps | UI components |
| Backend | Supabase (native) | Express/Fastify | No |
| Database | PostgreSQL (Supabase) | SQLite | No |
| GitHub | Native integration | Export | Export |
| Visual Editor | Yes | No | No |
| Authentication | Built-in | Manual | No |
| Deploy | Vercel/Netlify/other | Netlify | Vercel |
| Price (Pro) | $20/month | $20/month | $20/month |
How does Lovable work?
Application building workflow
1. DESCRIBE → Describe the application in natural language
↓
2. GENERATE → AI generates React + TypeScript code
↓
3. PREVIEW → See the working application
↓
4. EDIT → Modify through chat or visual editor
↓
5. CONNECT → Connect Supabase (auth, DB, storage)
↓
6. COMMIT → Automatic push to GitHub
↓
7. DEPLOY → Publish on Vercel/Netlify
↓
8. ITERATE → Continue developmentArchitecture of generated applications
my-lovable-app/
├── src/
│ ├── components/
│ │ ├── ui/ # Shadcn/ui components
│ │ ├── layout/ # Layout components
│ │ └── features/ # Feature-specific components
│ ├── pages/ # Route pages
│ ├── hooks/ # Custom React hooks
│ ├── lib/
│ │ ├── supabase.ts # Supabase client
│ │ └── utils.ts # Utility functions
│ ├── types/ # TypeScript types
│ ├── App.tsx # Main app component
│ └── main.tsx # Entry point
├── supabase/
│ └── migrations/ # Database migrations
├── tailwind.config.js
├── tsconfig.json
└── package.jsonGenerating applications
Effective prompts
Prompt template:
Build a [application type] for [goal/user].
Core features:
- [Main feature 1]
- [Main feature 2]
- [Main feature 3]
User flows:
- [How the user performs the main task]
- [Alternative paths]
Design requirements:
- [Visual style]
- [Responsiveness]
- [Branding]
Technical requirements:
- [Technical requirements]Prompt examples
SaaS Dashboard
Build a SaaS analytics dashboard for marketing teams.
Core features:
- User authentication (email + Google OAuth)
- Dashboard with key metrics (visitors, conversions, revenue)
- Multiple chart types (line, bar, pie, area)
- Date range selector with presets (7d, 30d, 90d, custom)
- Data export to CSV and PDF
- Team management (invite users, roles)
User flows:
- User logs in → sees dashboard → selects date range → views charts
- Admin invites team member → member receives email → creates account
Design requirements:
- Professional, clean look
- Dark mode support
- Responsive (works on tablet for presentations)
- Consistent color palette (blues and grays)
Technical requirements:
- TypeScript strict mode
- Recharts for charts
- React Query for data fetching
- Supabase for backendE-commerce Platform
Build an e-commerce platform for handmade crafts.
Core features:
- Product catalog with categories and tags
- Search with filters (price, category, rating)
- Shopping cart with persistent storage
- Wishlist functionality
- User accounts with order history
- Product reviews and ratings
- Seller dashboard for managing products
User flows:
- Browse products → add to cart → checkout → receive confirmation
- Seller creates account → adds products → manages orders
Design requirements:
- Warm, artisanal aesthetic
- High-quality product images showcase
- Mobile-first design
- Accessible (WCAG 2.1 AA)
Technical requirements:
- Supabase for products, orders, users
- Stripe integration ready (mock for now)
- Image optimization
- SEO-friendly URLsProject Management Tool
Build a project management tool like a simpler Trello.
Core features:
- Kanban boards with drag-and-drop
- Multiple boards per workspace
- Cards with title, description, due date, assignees
- Card comments and activity log
- Labels and priority tags
- Board sharing and permissions
User flows:
- User creates board → adds lists → creates cards → moves cards between lists
- User invites collaborator → collaborator joins → sees shared boards
Design requirements:
- Clean, minimal interface
- Smooth drag-and-drop animations
- Keyboard shortcuts
- Dark mode
Technical requirements:
- @hello-pangea/dnd for drag-and-drop
- Real-time updates with Supabase subscriptions
- Optimistic UI updatesIterative development
// Session 1: Basic application
You: "Build a task management app with categories and due dates"
Lovable: [Generates the basic application]
// Session 2: Adding authentication
You: "Add user authentication - users should only see their own tasks"
Lovable: [Configures Supabase Auth, adds RLS policies]
// Session 3: Visual editing
[You use the Visual Editor to adjust colors and layout]
// Session 4: New features
You: "Add task sharing - users can share specific tasks with others via email"
Lovable: [Adds sharing functionality]
// Session 5: Deploy
You: "Connect to GitHub and prepare for Vercel deployment"
Lovable: [Pushes to repo, configures build]Supabase integration
Automatic configuration
Lovable automatically configures Supabase when you ask for authentication or a database:
import { createClient } from '@supabase/supabase-js'
import type { Database } from '@/types/supabase'
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY
export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey)Authentication
import { useEffect, useState } from 'react'
import { User, Session } from '@supabase/supabase-js'
import { supabase } from '@/lib/supabase'
export function useAuth() {
const [user, setUser] = useState<User | null>(null)
const [session, setSession] = useState<Session | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session)
setUser(session?.user ?? null)
setLoading(false)
})
const { data: { subscription } } = supabase.auth.onAuthStateChange(
(_event, session) => {
setSession(session)
setUser(session?.user ?? null)
}
)
return () => subscription.unsubscribe()
}, [])
const signIn = async (email: string, password: string) => {
const { error } = await supabase.auth.signInWithPassword({
email,
password,
})
if (error) throw error
}
const signUp = async (email: string, password: string) => {
const { error } = await supabase.auth.signUp({
email,
password,
})
if (error) throw error
}
const signOut = async () => {
const { error } = await supabase.auth.signOut()
if (error) throw error
}
const signInWithGoogle = async () => {
const { error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
})
if (error) throw error
}
return {
user,
session,
loading,
signIn,
signUp,
signOut,
signInWithGoogle,
}
}Database with types
export interface Database {
public: {
Tables: {
tasks: {
Row: {
id: string
title: string
description: string | null
completed: boolean
due_date: string | null
user_id: string
category_id: string | null
created_at: string
updated_at: string
}
Insert: {
id?: string
title: string
description?: string | null
completed?: boolean
due_date?: string | null
user_id: string
category_id?: string | null
created_at?: string
updated_at?: string
}
Update: {
id?: string
title?: string
description?: string | null
completed?: boolean
due_date?: string | null
user_id?: string
category_id?: string | null
created_at?: string
updated_at?: string
}
}
categories: {
Row: {
id: string
name: string
color: string
user_id: string
created_at: string
}
Insert: {
id?: string
name: string
color: string
user_id: string
created_at?: string
}
Update: {
id?: string
name?: string
color?: string
user_id?: string
created_at?: string
}
}
}
}
}
export function useTasks() {
const { user } = useAuth()
return useQuery({
queryKey: ['tasks', user?.id],
queryFn: async () => {
const { data, error } = await supabase
.from('tasks')
.select('*, category:categories(*)')
.eq('user_id', user!.id)
.order('created_at', { ascending: false })
if (error) throw error
return data
},
enabled: !!user,
})
}Row Level Security (RLS)
Lovable automatically generates secure RLS policies:
CREATE TABLE tasks (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
completed BOOLEAN DEFAULT FALSE,
due_date TIMESTAMPTZ,
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
category_id UUID REFERENCES categories(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own tasks"
ON tasks FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own tasks"
ON tasks FOR INSERT
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own tasks"
ON tasks FOR UPDATE
USING (auth.uid() = user_id);
CREATE POLICY "Users can delete own tasks"
ON tasks FOR DELETE
USING (auth.uid() = user_id);
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER tasks_updated_at
BEFORE UPDATE ON tasks
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();Real-time subscriptions
export function useRealtimeTasks() {
const { user } = useAuth()
const queryClient = useQueryClient()
useEffect(() => {
if (!user) return
const channel = supabase
.channel('tasks-changes')
.on(
'postgres_changes',
{
event: '*',
schema: 'public',
table: 'tasks',
filter: `user_id=eq.${user.id}`,
},
(payload) => {
queryClient.invalidateQueries({ queryKey: ['tasks'] })
}
)
.subscribe()
return () => {
supabase.removeChannel(channel)
}
}, [user, queryClient])
}GitHub integration
Automatic commits
Lovable automatically commits changes to the connected GitHub repository:
// GitHub workflow
1. Connect your GitHub account in Lovable settings
2. Create a new repo or connect an existing one
3. Every change → automatic commit with a descriptive message
4. Change history available in GitHub
// Example commit messages generated by Lovable:
- "feat: Add user authentication with Supabase"
- "style: Update dashboard layout and colors"
- "fix: Resolve task deletion bug"
- "feat: Add category filtering to tasks"Branch management
// Lovable supports branch-based workflows
// In your project settings you can:
// 1. Choose the default branch (main/develop)
// 2. Create feature branches
// 3. Merge through Pull Requests
// Example workflow:
// main ← PR ← feature/add-categories
// ← PR ← feature/dark-mode
// ← PR ← fix/mobile-responsivePull Requests
# Automatically generated PR
## Summary
Added category filtering functionality to the tasks view.
## Changes
- Added CategoryFilter component
- Updated useTasks hook to support filtering
- Added filter state to TasksPage
- Updated database queries for category filtering
## Screenshots
[Lovable automatically adds screenshots of the changes]
## Testing
- [x] Category filter displays all categories
- [x] Selecting category filters tasks correctly
- [x] "All" option shows all tasks
- [x] Filter persists on page refreshVisual Editor
Editing without coding
The Visual Editor lets you modify components directly:
// Visual Editor capabilities:
1. LAYOUT
- Drag & drop elements
- Resize components
- Change flex/grid settings
- Spacing (margin, padding)
2. STYLING
- Colors (background, text, border)
- Typography (font, size, weight)
- Shadows and effects
- Border radius
3. CONTENT
- Inline text editing
- Image replacement
- Link modification
4. RESPONSIVE
- Preview at different breakpoints
- Hide elements per device
- Responsive spacingVisual Editor usage example
Scenario: Customizing a product card
1. Click on the product card
2. In the right panel:
- Change background to #f8f9fa
- Add shadow-md
- Increase padding to 24px
- Round corners to 12px
3. Click on the product title:
- Change font-weight to 600
- Set color to #1a1a1a
4. Preview on mobile:
- Reduce padding on mobile to 16px
- Change layout to vertical
5. Save → automatic commit to GitHubPractical examples
Blog platform with CMS
Prompt: "Build a blog platform with admin panel for content management.
Features:
- Public blog with posts list and detail pages
- Admin panel with WYSIWYG editor
- Categories and tags
- Featured posts
- SEO metadata per post
- Draft/published status
- Scheduled publishing
Design:
- Clean, typography-focused
- Reading time estimates
- Related posts
- Dark mode
- Newsletter signup"Generated structure:
blog-platform/
├── src/
│ ├── components/
│ │ ├── blog/
│ │ │ ├── PostCard.tsx
│ │ │ ├── PostContent.tsx
│ │ │ ├── PostMeta.tsx
│ │ │ ├── RelatedPosts.tsx
│ │ │ └── Newsletter.tsx
│ │ ├── admin/
│ │ │ ├── PostEditor.tsx # WYSIWYG editor
│ │ │ ├── PostList.tsx
│ │ │ ├── MediaLibrary.tsx
│ │ │ └── SEOFields.tsx
│ │ └── layout/
│ │ ├── Header.tsx
│ │ ├── Footer.tsx
│ │ └── Sidebar.tsx
│ ├── pages/
│ │ ├── index.tsx # Blog home
│ │ ├── posts/[slug].tsx # Post detail
│ │ ├── category/[slug].tsx # Category archive
│ │ └── admin/
│ │ ├── index.tsx # Admin dashboard
│ │ ├── posts/index.tsx # Posts list
│ │ ├── posts/new.tsx # Create post
│ │ └── posts/[id].tsx # Edit post
│ ├── hooks/
│ │ ├── usePosts.ts
│ │ ├── useCategories.ts
│ │ └── useAdmin.ts
│ └── lib/
│ ├── supabase.ts
│ └── markdown.ts
└── supabase/
└── migrations/
├── 001_posts.sql
├── 002_categories.sql
└── 003_tags.sqlMarketplace with payments
Prompt: "Build a marketplace for digital products (templates, icons, fonts).
Features:
- Product listings with categories
- Seller profiles and stores
- Shopping cart and checkout
- Digital file delivery after purchase
- Seller dashboard with analytics
- Review and rating system
- Search with filters
Integrations:
- Supabase for data and auth
- Stripe for payments (mock for development)
- Cloudinary for file storage
Design:
- Modern, creative marketplace look
- Grid layouts for products
- Product previews
- Responsive design"import { useState } from 'react'
import { supabase } from '@/lib/supabase'
import { useAuth } from './useAuth'
interface CartItem {
productId: string
price: number
sellerId: string
}
export function useCheckout() {
const { user } = useAuth()
const [loading, setLoading] = useState(false)
const checkout = async (items: CartItem[]) => {
if (!user) throw new Error('Must be logged in')
setLoading(true)
try {
const { data: order, error: orderError } = await supabase
.from('orders')
.insert({
user_id: user.id,
total: items.reduce((sum, item) => sum + item.price, 0),
status: 'pending',
})
.select()
.single()
if (orderError) throw orderError
const orderItems = items.map((item) => ({
order_id: order.id,
product_id: item.productId,
price: item.price,
seller_id: item.sellerId,
}))
const { error: itemsError } = await supabase
.from('order_items')
.insert(orderItems)
if (itemsError) throw itemsError
const response = await fetch('/api/create-checkout-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ orderId: order.id }),
})
const { sessionUrl } = await response.json()
window.location.href = sessionUrl
} finally {
setLoading(false)
}
}
return { checkout, loading }
}SaaS with subscriptions
Prompt: "Build a SaaS application for expense tracking with team features.
Features:
- User authentication with email and Google
- Personal and team workspaces
- Expense logging with categories
- Receipt photo upload
- Monthly/yearly reports with charts
- Export to CSV/PDF
- Subscription tiers (Free, Pro, Team)
- Billing management
Tiers:
- Free: 50 expenses/month, 1 user
- Pro ($10/mo): Unlimited expenses, reports, 1 user
- Team ($25/mo): Everything + 5 users, shared workspaces
Design:
- Professional, trustworthy look
- Dashboard-focused
- Quick expense entry
- Mobile-friendly for on-the-go logging"import { useAuth } from './useAuth'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { supabase } from '@/lib/supabase'
type SubscriptionTier = 'free' | 'pro' | 'team'
interface Subscription {
id: string
user_id: string
tier: SubscriptionTier
status: 'active' | 'canceled' | 'past_due'
current_period_end: string
stripe_subscription_id: string | null
}
export function useSubscription() {
const { user } = useAuth()
const queryClient = useQueryClient()
const { data: subscription, isLoading } = useQuery({
queryKey: ['subscription', user?.id],
queryFn: async () => {
const { data, error } = await supabase
.from('subscriptions')
.select('*')
.eq('user_id', user!.id)
.single()
if (error && error.code !== 'PGRST116') throw error
return data as Subscription | null
},
enabled: !!user,
})
const tier = subscription?.tier ?? 'free'
const limits = {
free: { expenses: 50, users: 1, reports: false },
pro: { expenses: Infinity, users: 1, reports: true },
team: { expenses: Infinity, users: 5, reports: true },
}
const currentLimits = limits[tier]
const upgradeMutation = useMutation({
mutationFn: async (newTier: SubscriptionTier) => {
const response = await fetch('/api/create-subscription', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ tier: newTier }),
})
return response.json()
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] })
},
})
const cancelMutation = useMutation({
mutationFn: async () => {
const response = await fetch('/api/cancel-subscription', {
method: 'POST',
})
return response.json()
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] })
},
})
return {
subscription,
tier,
limits: currentLimits,
isLoading,
upgrade: upgradeMutation.mutate,
cancel: cancelMutation.mutate,
isUpgrading: upgradeMutation.isPending,
isCanceling: cancelMutation.isPending,
}
}Deploy
Vercel (recommended)
# Lovable automatically prepares the project for Vercel
# 1. Connect the GitHub repo to Vercel
# 2. Set environment variables:
VITE_SUPABASE_URL=your-supabase-url
VITE_SUPABASE_ANON_KEY=your-anon-key
# 3. Deploy - Vercel automatically:
# - Detects Vite
# - Builds the application
# - Deploys to the edge networkNetlify
# netlify.toml - automatically generated
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "18"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Environment variables
# .env.example - generated by Lovable
# Supabase
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
# Optional: Stripe (for payments)
VITE_STRIPE_PUBLIC_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Optional: Analytics
VITE_POSTHOG_KEY=phc_...Lovable pricing (2025)
Free plan
Price: $0/month
Includes:
- 5 generations/month
- Public projects
- Community support
- Basic export
Starter plan
Price: $20/month
Includes:
- 100 generations/month
- Private projects
- GitHub integration
- Supabase integration
- Visual Editor
- Email support
Pro plan
Price: $50/month
Includes:
- Unlimited generations
- Everything from Starter
- Priority generation
- Advanced features
- Custom domains
- Priority support
Team plan
Price: Custom
Includes:
- Everything from Pro
- Team collaboration
- Shared workspaces
- Admin dashboard
- SSO integration
- Dedicated support
Best practices
Effective prompting
// ✅ Good prompt
"Build a task management app with:
- User authentication (email + Google)
- Tasks with title, description, due date, priority
- Categories with custom colors
- Drag-and-drop between status columns
- Dark mode support
Use Supabase for backend. Design should be clean
and professional, similar to Linear or Notion."
// ❌ Weak prompt
"Make me a task app" // Too vague
"Copy Notion exactly" // Unrealistic
"Add everything" // UnspecifiedIterative development
// Instead of one massive prompt:
// ❌ "Build complete e-commerce with auth, products, cart, checkout, admin, analytics..."
// Build incrementally:
// ✅ Session 1: "Build product catalog with categories and search"
// ✅ Session 2: "Add user authentication with Supabase"
// ✅ Session 3: "Add shopping cart with persistence"
// ✅ Session 4: "Build checkout flow"
// ✅ Session 5: "Add admin panel for products"Using the Visual Editor
// When to use Visual Editor vs Chat:
// Visual Editor for:
- Adjusting colors and styles
- Changing layout and spacing
- Fixing responsive design
- Minor visual tweaks
// Chat for:
- New functionality
- Business logic
- API integrations
- Complex structural changesFAQ - frequently asked questions
Can I export the code and develop locally?
Yes! Lovable generates standard React/TypeScript code. You can:
- Clone the repo from GitHub
npm install && npm run dev- Continue development in any IDE
How does the Supabase integration work?
Lovable automatically:
- Creates a Supabase project (or connects an existing one)
- Generates database migrations
- Configures Row Level Security
- Creates TypeScript types
- Implements hooks for data fetching
Does Lovable support other databases?
Currently Lovable natively supports only Supabase (PostgreSQL). For other databases you can:
- Write your own integrations after exporting
- Use Supabase as primary and synchronize with others
How to handle payments?
Lovable can generate a Stripe integration (mock in development). For production:
- Create a Stripe account
- Add keys to environment variables
- Ask Lovable to "Make Stripe integration production-ready"
Can I use my own components?
After exporting, yes. Within Lovable you can also ask for specific libraries:
- "Use shadcn/ui for all components"
- "Use Radix UI primitives"
- "Use Framer Motion for animations"
Summary
Lovable is an advanced platform for building web applications that stands out with:
- Professional workflow - GitHub + Supabase native
- Visual editing - Modifications without coding
- Production-ready - TypeScript, RLS, best practices
- Flexible deploy - Vercel, Netlify, self-hosting
- Team-ready - Collaboration and sharing
It is ideal for startups, freelancers, and teams looking to quickly build production-grade applications.