Antigravity + Supabase: Build a Complete App in 30 Minutes (Step-by-Step Tutorial) | Antigravity AI Directory | Google Antigravity DirectoryTutorialsAntigravity + Supabase: Build a Complete App in 30 Minutes (Step-by-Step Tutorial)
Antigravity + Supabase: Build a Complete App in 30 Minutes
What We're Building
In this tutorial, we'll build QuickNotes—a collaborative note-taking app with:
- User authentication (email + Google OAuth)
- Notes with title, content, and tags
- Real-time collaboration (changes sync instantly)
- Sharing notes with other users
- Full-text search
- Production deployment
Tech Stack:
- Frontend: Next.js 15 (App Router)
- Backend: Supabase (Auth, Database, Realtime)
- AI Assistant: Google Antigravity
- Styling: Tailwind CSS
Prerequisites
- VS Code with Antigravity extension installed
- Node.js 18+ installed
- A Supabase account (free tier works fine)
Phase 1: Project Setup (5 minutes)
Step 1: Create Supabase Project
- Go to supabase.com
- Click "New Project"
- Name: "quicknotes"
- Generate a strong database password (save it!)
- Choose the region closest to you
- Wait for setup (~2 minutes)
Step 2: Initialize Next.js Project with Antigravity
Open Agent Mode (Cmd+Shift+A) and use this prompt:
"Create a new Next.js 15 project called 'quicknotes' with:
- App Router with TypeScript
- Tailwind CSS
- Supabase client library (@supabase/supabase-js and @supabase/ssr)
- Proper folder structure: components/, lib/, types/
- Environment variables template for Supabase
- A basic layout with header component
- Dark mode support
Also create a .antigravity file with rules for this project."
Step 3: Configure Environment Variables
Create .env.local with your Supabase credentials:
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Related Posts
Next.js 15 + Antigravity: The Ultimate React Developer Workflow (2025)
Master the perfect Next.js 15 development workflow with Google Antigravity. Learn Server Components, Server Actions, App Router patterns, and production-ready prompts that 10x your React development speed.
Antigravity for Python Developers: Django, FastAPI & Flask Complete Workflows (2025)
Master Google Antigravity for Python development. Complete guide covering Django, FastAPI, and Flask workflows with production-ready prompts, MCP server integrations, and real-world examples.
Building Full-Stack Apps with Antigravity Agent Mode: From Prompt to Production (2025)
Master Antigravity's Agent Mode to build complete full-stack applications autonomously. This step-by-step tutorial takes you from a simple prompt to a deployed production app with authentication, database, and payments.
Phase 2: Database Schema (5 minutes)
Step 1: Generate Database Schema
Use this prompt in Agent Mode:
"Create a Supabase migration for QuickNotes:
Tables needed:
- profiles (extends auth.users) - id, username, full_name, avatar_url
- notes - id, user_id, title, content, is_public, timestamps
- note_tags (junction table) - note_id, tag
- note_shares - note_id, shared_with_user_id, permission
Include:
- Row Level Security policies for all tables
- Proper indexes for performance
- Trigger to create profile on user signup
- Full-text search index on notes"
Phase 3: Authentication (7 minutes)
Step 1: Generate Auth Components
"Create complete authentication for QuickNotes using Supabase Auth:
Pages:
- /sign-in - Email/password + Google OAuth
- /sign-up - Email/password with username
- /auth/callback - OAuth callback handler
Components:
- AuthForm (reusable for sign-in/sign-up)
- OAuthButtons (Google sign-in)
- SignOutButton
Also create:
- Supabase client utilities (browser and server)
- Middleware for protected routes
- AuthProvider context"
Phase 4: Core Features (10 minutes)
Step 1: Build Note Editor
"Create the note editing system for QuickNotes:
Pages:
- /dashboard - List of user's notes with search and tag filtering
- /notes/new - Create new note
- /notes/[id] - View/edit note
- /notes/[id]/share - Share settings for a note
Components:
- NoteCard - Preview card for note list
- NoteEditor - Rich text editor for note content
- TagInput - Add/remove tags on notes
- ShareDialog - Modal to share note with other users
- SearchBar - Full-text search across notes
Server Actions:
- createNote(formData)
- updateNote(noteId, formData)
- deleteNote(noteId)
- shareNote(noteId, email, permission)
- searchNotes(query)
Include:
- Optimistic updates
- Loading states
- Error handling
- Autosave for note content (debounced)"
Generated Note Editor Example
'use client'
import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import { updateNote } from '@/app/actions'
import { TagInput } from './TagInput'
import { useDebouncedCallback } from 'use-debounce'
interface NoteEditorProps {
note: {
id: string
title: string
content: string
tags: string[]
is_public: boolean
}
}
export function NoteEditor({ note }: NoteEditorProps) {
const router = useRouter()
const [title, setTitle] = useState(note.title)
const [content, setContent] = useState(note.content)
const [isSaving, setIsSaving] = useState(false)
const [lastSaved, setLastSaved] = useState<Date | null>(null)
const debouncedSave = useDebouncedCallback(
async (updates) => {
setIsSaving(true)
try {
await updateNote(note.id, updates)
setLastSaved(new Date())
} catch (error) {
console.error('Failed to save:', error)
} finally {
setIsSaving(false)
}
},
1000
)
useEffect(() => {
debouncedSave({ title, content })
}, [title, content, debouncedSave])
return (
<div className="max-w-4xl mx-auto p-6">
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Note title..."
className="w-full text-3xl font-bold border-none outline-none mb-4"
/>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="Start writing..."
className="w-full h-[60vh] text-lg border-none outline-none resize-none"
/>
{isSaving ? (
<span className="text-sm text-gray-500">Saving...</span>
) : lastSaved ? (
<span className="text-sm text-green-600">
Saved {lastSaved.toLocaleTimeString()}
</span>
) : null}
</div>
)
}
Phase 5: Real-Time Collaboration (5 minutes)
Step 1: Add Real-Time Subscriptions
"Add real-time updates to QuickNotes:
- When viewing a shared note, show live updates from other editors
- In the dashboard, show new/updated notes instantly
- Show a presence indicator (who else is viewing/editing)
Use Supabase Realtime with proper:
- Subscription management (cleanup on unmount)
- Error handling
- Reconnection logic"
Generated Real-Time Hook
'use client'
import { useEffect, useState } from 'react'
import { createClient } from '@/lib/supabase/client'
import type { Note } from '@/types'
export function useRealtimeNote(noteId: string, initialNote: Note) {
const [note, setNote] = useState(initialNote)
const [isConnected, setIsConnected] = useState(false)
const [viewers, setViewers] = useState<string[]>([])
useEffect(() => {
const supabase = createClient()
const noteChannel = supabase
.channel(`note:${noteId}`)
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'notes',
filter: `id=eq.${noteId}`,
},
(payload) => {
setNote((current) => ({ ...current, ...payload.new }))
}
)
.subscribe((status) => {
setIsConnected(status === 'SUBSCRIBED')
})
const presenceChannel = supabase
.channel(`presence:${noteId}`)
.on('presence', { event: 'sync' }, () => {
const state = presenceChannel.presenceState()
const userIds = Object.values(state).flat().map((p: any) => p.user_id)
setViewers(userIds)
})
.subscribe()
return () => {
noteChannel.unsubscribe()
presenceChannel.unsubscribe()
}
}, [noteId])
return { note, isConnected, viewers }
}
Phase 6: Polish and Deploy (5 minutes)
Step 1: Final Polish
Quick prompts for finishing touches:
"Add a loading skeleton component for the notes list"
"Add keyboard shortcuts: Cmd+S to save, Cmd+N for new note, Cmd+K for search"
"Add proper meta tags and SEO for all pages"
Step 2: Deploy to Vercel
- Push to GitHub
- Import project in Vercel
- Add environment variables (Supabase URL and key)
- Deploy!
Step 3: Update Supabase Settings
- Go to Authentication → URL Configuration
- Add your Vercel URL to Site URL and Redirect URLs
Common Issues and Fixes
Issue: "Invalid API Key"
Check your .env.local file has the correct Supabase URL and anon key.
Issue: RLS Blocking Queries
Make sure you're signed in. Check the RLS policies in Supabase.
Issue: Real-time Not Working
Verify the table is added to supabase_realtime publication.
Issue: OAuth Redirect Error
Verify your redirect URLs in Supabase match exactly.
Extending the App
Add Markdown Support
"Add markdown rendering to note content. Use react-markdown with syntax highlighting."
Add Note Templates
"Create a template system: users can save note templates and create new notes from templates."
Add Export
"Add ability to export notes as Markdown files or PDF."
FAQs
Can I use a different database?
This tutorial is Supabase-specific, but the patterns work with any PostgreSQL database.
How much does Supabase cost?
The free tier includes 500MB database, 50,000 monthly active users, and 2GB file storage.
Can I add mobile apps?
Yes! Supabase has React Native and Flutter SDKs.
How do I handle file uploads?
Use Supabase Storage. Ask Antigravity: "Add image attachments to notes using Supabase Storage."
Conclusion
In 30 minutes, you've built a full-stack application with:
- User authentication
- Database with proper security
- Real-time collaboration
- Search functionality
- Sharing system
- Production deployment
This is the power of Antigravity + Supabase. You focus on what you're building, not how to wire up authentication or set up database tables.
Next Steps