Vibe Coding กับ Database — สอนใช้ Cursor + Supabase
หนึ่งในคำถามที่ได้ยินบ่อยที่สุดจากคนที่เริ่มต้น Vibe Coding คือ — "แล้วถ้าอยากให้ app เก็บข้อมูลได้จริงๆ ต้องทำยังไง?"
Frontend สวยได้ด้วย Cursor + Claude แต่ถ้าไม่มี database ข้อมูลก็หายไปทุกครั้งที่รีเฟรชหน้า ปัญหานี้แก้ได้ง่ายมากด้วย Supabase — backend ที่ออกแบบมาให้นักพัฒนา (และ Vibe Coder) ใช้งานได้เร็วที่สุดในโลก
บทความนี้จะพาคุณจาก "ไม่มี database" ไปถึง "มี CRUD app ที่ทำงานได้จริง" ภายใน 30 นาที โดยใช้ Cursor เป็นตัวช่วยเขียนโค้ด
ถ้ายังไม่รู้จัก Vibe Coding เลย แนะนำให้อ่าน Vibe Coding คืออะไร — คู่มือฉบับสมบูรณ์ ก่อน
1. ทำไม Supabase ถึงเป็น Backend ที่ดีที่สุดสำหรับ Vibe Coding
เวลาเริ่มโปรเจกต์ใหม่ด้วย Vibe Coding คุณมีตัวเลือก backend หลายอย่าง — Firebase, PlanetScale, Neon, Railway แต่ละอันมีข้อดีต่างกัน แต่ Supabase มีสิ่งที่ทำให้มันโดดเด่นกว่าสำหรับงาน Vibe Coding โดยเฉพาะ
เหตุผลที่ 1: Cursor รู้จัก Supabase API ดีมาก
เนื่องจาก Supabase เป็น open-source และมี documentation สาธารณะจำนวนมาก Claude (ที่อยู่ใน Cursor) จึงรู้ pattern การใช้งานเป็นอย่างดี พิมพ์ว่า "สร้าง function ดึงข้อมูล users จาก Supabase" แล้ว Cursor จะเขียน code ที่ถูกต้องได้ทันที ไม่ต้องแก้ไขเพิ่มเติมมาก
เหตุผลที่ 2: JavaScript SDK ใช้งานง่ายมาก
Supabase JS SDK ถูกออกแบบให้ readable สูง ทำให้ Vibe Coder อ่านแล้วเข้าใจได้ว่า code ทำอะไร แม้จะไม่มีพื้นฐาน programming
เหตุผลที่ 3: Free tier ใจกว้าง
Project ฟรีได้ถึง 500MB database, 2GB bandwidth, unlimited API requests สำหรับ prototype หรือ side project ไม่ต้องจ่ายเงินเลย
เหตุผลที่ 4: ครบในที่เดียว
Database + Authentication + File Storage + Realtime + Edge Functions — ทุกอย่างมาพร้อมกัน ไม่ต้องต่อ service แยก 5 อัน
2. Supabase คืออะไร — รู้ก่อนสร้าง
Supabase คือ open-source Firebase alternative ที่ใช้ PostgreSQL เป็น database หลัก
ประกอบด้วย 4 ส่วนหลัก:
PostgreSQL Database
Database หลักที่เก็บข้อมูลทั้งหมด เป็น PostgreSQL จริงๆ ใช้ SQL ได้เต็มรูปแบบ ต้องการ query ซับซ้อนแค่ไหนก็ได้ รองรับ JSON fields, full-text search, geographic data
Authentication
ระบบ auth สำเร็จรูป รองรับ Email/Password, Magic Link, OAuth (Google, GitHub, Facebook) ฯลฯ ไม่ต้องเขียน auth logic เอง Cursor จัดการได้หมด
Storage
File storage สำหรับ images, videos, documents สร้าง bucket, ตั้ง permission ได้ผ่าน dashboard มี CDN ในตัว
Realtime
Subscribe ดู database changes แบบ real-time ใช้ WebSocket เหมาะสำหรับ chat app, live dashboard, collaborative tools
3. Setup Project แรกใน 5 นาที
เริ่มจากสร้าง Supabase project ก่อน ทำตามขั้นตอนนี้:
ขั้นตอนที่ 1: สร้าง Account และ Project
- ไปที่ supabase.com แล้ว Sign Up ด้วย GitHub account
- กด New project
- ตั้งชื่อ project (เช่น
my-vibe-app) - ตั้ง database password (จดไว้ — ใช้อีก)
- เลือก region ที่ใกล้ที่สุด (Singapore สำหรับคนไทย)
- กด Create new project รอประมาณ 2 นาที
ขั้นตอนที่ 2: ดึง API Keys
หลัง project สร้างเสร็จ ไปที่ Settings → API แล้วก็อป:
- Project URL — เป็น URL ที่ใช้เชื่อมต่อ
- anon/public key — ใช้ใน frontend code
ขั้นตอนที่ 3: ติดตั้ง Supabase ใน Next.js Project
ใน terminal ของ Cursor ให้รัน:
npm install @supabase/supabase-js
สร้างไฟล์ .env.local ใน root ของ project:
NEXT_PUBLIC_SUPABASE_URL=your_project_url_here
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_here
สร้างไฟล์ lib/supabase.ts:
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
เพียงเท่านี้ backend ก็พร้อมใช้งานแล้ว
4. ขอให้ Cursor สร้าง Schema + RLS Policies
นี่คือส่วนที่ Vibe Coding เจ๋งมาก แทนที่จะต้องนั่งเขียน SQL เอง ให้ Cursor ทำให้
วิธี Prompt ใน Cursor
เปิด Cursor แล้วพิมพ์ใน chat:
"ฉันกำลังสร้าง task management app ด้วย Supabase PostgreSQL ช่วยสร้าง SQL schema สำหรับตาราง tasks ที่มี: id, title, description, status (todo/in-progress/done), created_at, updated_at, user_id (foreign key ไปยัง auth.users) พร้อม RLS policies ที่ให้ user เห็นและแก้ไขได้เฉพาะ tasks ของตัวเอง"
Cursor จะ generate SQL ออกมาแบบนี้:
-- สร้างตาราง tasks
CREATE TABLE tasks (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'todo' CHECK (status IN ('todo', 'in-progress', 'done')),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL
);
-- เปิด Row Level Security
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;
-- Policy: user เห็นได้เฉพาะ tasks ของตัวเอง
CREATE POLICY "Users can view own tasks" ON tasks
FOR SELECT USING (auth.uid() = user_id);
-- Policy: user สร้าง task ให้ตัวเองได้
CREATE POLICY "Users can insert own tasks" ON tasks
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- Policy: user แก้ไข tasks ของตัวเองได้
CREATE POLICY "Users can update own tasks" ON tasks
FOR UPDATE USING (auth.uid() = user_id);
-- Policy: user ลบ tasks ของตัวเองได้
CREATE POLICY "Users can delete own tasks" ON tasks
FOR DELETE USING (auth.uid() = user_id);
-- Auto-update updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_tasks_updated_at
BEFORE UPDATE ON tasks
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
วิธี Run SQL ใน Supabase
ไปที่ Supabase Dashboard → SQL Editor แล้ว paste SQL ด้านบนแล้วกด Run
RLS (Row Level Security) สำคัญมาก มันป้องกันไม่ให้ user คนหนึ่งเห็นข้อมูลของ user อื่น ถือเป็น best practice สำหรับทุก Supabase project
5. Generate TypeScript Types อัตโนมัติ
Supabase มี CLI ที่สามารถ generate TypeScript types จาก database schema ได้อัตโนมัติ ทำให้ Cursor ช่วยเขียน code ได้แม่นยำขึ้นมาก
ติดตั้ง Supabase CLI
npm install -g supabase
Login และ Generate Types
# Login ด้วย access token จาก Supabase Dashboard → Settings → Access Tokens
supabase login
# Generate types (แทนที่ <project-id> ด้วย Project ID ของคุณ)
supabase gen types typescript --project-id <project-id> > lib/database.types.ts
อัปเดต Supabase Client ให้ใช้ Types
import { createClient } from '@supabase/supabase-js'
import type { Database } from './database.types'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey)
หลังจากนี้ เวลาพิมพ์ supabase.from('tasks') ใน Cursor จะมี autocomplete บอก columns ทั้งหมดที่มีในตาราง ลด error จากการพิมพ์ชื่อ column ผิดได้เยอะมาก
6. ตัวอย่าง: สร้าง CRUD App ใน 30 นาที
มาลงมือสร้าง Task Manager app จริงๆ กัน โดยใช้ Cursor ช่วย
โครงสร้าง Function ที่ต้องมี
บอก Cursor ว่าต้องการอะไร:
"ช่วยสร้าง custom hook
useTasksสำหรับ Next.js ที่ใช้ Supabase เพื่อ: ดึง tasks ทั้งหมดของ user ที่ login อยู่, สร้าง task ใหม่, อัปเดต status ของ task, ลบ task"
Cursor จะเขียน code ออกมาประมาณนี้:
// hooks/useTasks.ts
import { useState, useEffect } from 'react'
import { supabase } from '@/lib/supabase'
type Task = {
id: string
title: string
description: string | null
status: 'todo' | 'in-progress' | 'done'
created_at: string
updated_at: string
user_id: string
}
export function useTasks() {
const [tasks, setTasks] = useState<Task[]>([])
const [loading, setLoading] = useState(true)
// ดึง tasks ทั้งหมด
const fetchTasks = async () => {
setLoading(true)
const { data, error } = await supabase
.from('tasks')
.select('*')
.order('created_at', { ascending: false })
if (!error && data) {
setTasks(data)
}
setLoading(false)
}
// สร้าง task ใหม่
const createTask = async (title: string, description?: string) => {
const { data, error } = await supabase
.from('tasks')
.insert({ title, description })
.select()
.single()
if (!error && data) {
setTasks(prev => [data, ...prev])
}
return { data, error }
}
// อัปเดต status
const updateTaskStatus = async (id: string, status: Task['status']) => {
const { error } = await supabase
.from('tasks')
.update({ status })
.eq('id', id)
if (!error) {
setTasks(prev =>
prev.map(task => task.id === id ? { ...task, status } : task)
)
}
return { error }
}
// ลบ task
const deleteTask = async (id: string) => {
const { error } = await supabase
.from('tasks')
.delete()
.eq('id', id)
if (!error) {
setTasks(prev => prev.filter(task => task.id !== id))
}
return { error }
}
useEffect(() => {
fetchTasks()
}, [])
return { tasks, loading, createTask, updateTaskStatus, deleteTask }
}
หน้า UI หลัก
"ช่วยสร้าง TaskList component ที่ใช้ hook
useTasksแสดง tasks เป็น list มีปุ่ม เปลี่ยน status และลบ task แต่ละอัน รวมถึงฟอร์มสร้าง task ใหม่ ออกแบบ UI ด้วย Tailwind CSS ให้ดูสะอาดและ modern"
ใน 5 นาทีคุณจะมี component ที่ทำงานได้จริง — ไม่ต้องเขียนโค้ดเองสักบรรทัด
สำหรับการ deploy ขั้นตอนถัดไปอ่านได้ที่ วิธี Deploy Next.js App ขึ้น Vercel ด้วย Vibe Coding
7. Tips ขั้นสูง: Migration, Edge Functions, Auth Flow
Database Migration
เมื่อต้องการเปลี่ยน schema ในภายหลัง อย่าแก้โดยตรงใน dashboard ให้บอก Cursor:
"ฉันต้องการเพิ่ม column
priority(low/medium/high) ใน tasks table และ columndue_dateแบบ optional ช่วยเขียน SQL migration ที่ปลอดภัย ไม่ทำลายข้อมูลเดิม"
Cursor จะเขียน ALTER TABLE แบบที่ safe กว่าการลบ table แล้วสร้างใหม่
ALTER TABLE tasks
ADD COLUMN priority TEXT DEFAULT 'medium'
CHECK (priority IN ('low', 'medium', 'high')),
ADD COLUMN due_date TIMESTAMPTZ;
Edge Functions
สำหรับ business logic ที่ซับซ้อนหรือต้องการ server-side processing ใช้ Supabase Edge Functions:
"ช่วยสร้าง Supabase Edge Function ที่ส่ง email notification เมื่อ task ถูกสร้างใหม่ โดยใช้ Resend API"
Edge Functions คือ Deno functions ที่รันบน Supabase servers เหมาะสำหรับ webhook, cron jobs, หรือ operations ที่ต้องการ secret keys
Auth Flow
Supabase Auth กับ Next.js ตั้งค่าได้ด้วย @supabase/ssr package:
"ช่วย setup Supabase Auth ใน Next.js 14 App Router ให้มี middleware ป้องกัน routes ที่ต้อง login และมีหน้า login/logout"
Cursor จะสร้าง middleware.ts, auth helper functions และ login page ให้ครบ
สำหรับ setup Cursor ที่สมบูรณ์ อ่านได้ที่ Cursor + Claude Vibe Coding Setup ฉบับสมบูรณ์
8. Common Pitfalls + วิธีแก้
ข้อผิดพลาดที่พบบ่อยเมื่อเริ่มใช้ Supabase กับ Vibe Coding และวิธีแก้:
Pitfall 1: RLS ทำให้ดึงข้อมูลไม่ได้
อาการ: Query คืนค่า empty array ทั้งที่มีข้อมูลอยู่
สาเหตุ: เปิด RLS แต่ยังไม่ได้สร้าง policies หรือ user ยังไม่ได้ login
วิธีแก้: ตรวจสอบใน Supabase Dashboard → Authentication → Policies ว่ามี policy สำหรับ SELECT หรือเปล่า และตรวจสอบว่า user session ถูกต้อง
// เช็ค session ก่อน query
const { data: { session } } = await supabase.auth.getSession()
if (!session) {
// redirect ไปหน้า login
return
}
Pitfall 2: Environment Variables ใช้งานไม่ได้ใน Production
อาการ: App ทำงานใน local แต่ใน Vercel ดึงข้อมูลไม่ได้
สาเหตุ: ลืม set environment variables ใน Vercel dashboard
วิธีแก้: ไปที่ Vercel → Project Settings → Environment Variables แล้ว add NEXT_PUBLIC_SUPABASE_URL และ NEXT_PUBLIC_SUPABASE_ANON_KEY
Pitfall 3: CORS Error เวลา Upload ไฟล์
อาการ: Upload file ไปยัง Supabase Storage แล้วเจอ CORS error
วิธีแก้: ไปที่ Supabase Dashboard → Storage → Policies แล้วเพิ่ม CORS policy ให้ถูกต้อง หรือบอก Cursor:
"ฉันเจอ CORS error เวลา upload ไฟล์ไปยัง Supabase Storage จาก localhost:3000 ช่วยแก้ไขให้หน่อย"
Pitfall 4: N+1 Query Problem
อาการ: App ช้าผิดปกติเมื่อมีข้อมูลเยอะ
สาเหตุ: ดึงข้อมูล list แล้วค่อย loop ดึง related data ทีละรายการ
วิธีแก้: ใช้ Supabase's relationship query แทน:
// ไม่ดี — ดึงทีละ user
const tasks = await supabase.from('tasks').select('*')
for (const task of tasks.data) {
const user = await supabase.from('profiles').select('*').eq('id', task.user_id)
}
// ดี — ดึงพร้อมกันครั้งเดียว
const { data } = await supabase
.from('tasks')
.select('*, profiles(name, avatar_url)')
Pitfall 5: Forgetting to Handle Errors
อาการ: App crash โดยไม่มี error message ที่ชัดเจน
วิธีแก้: เสมอ destructure error จาก Supabase response:
const { data, error } = await supabase.from('tasks').select('*')
if (error) {
console.error('Error fetching tasks:', error.message)
// แจ้ง user ด้วย toast หรือ error state
return
}
บอก Cursor ว่า "เพิ่ม error handling ที่ครอบคลุมใน useTasks hook" แล้วมันจะเพิ่มให้อัตโนมัติ
Vibe Coding + Supabase = Stack ที่ทรงพลังที่สุดสำหรับมือใหม่
สรุปสิ่งที่คุณทำได้ตอนนี้:
- ตั้ง Supabase project ได้ใน 5 นาที
- ขอให้ Cursor เขียน SQL schema + RLS policies ให้
- Generate TypeScript types อัตโนมัติ
- สร้าง CRUD operations โดยใช้ Supabase JavaScript SDK
- หลีกเลี่ยง pitfalls ที่พบบ่อย
Supabase กับ Cursor เป็น combo ที่ทำให้ Vibe Coding ไปได้ไกลกว่าแค่ static website มาก คุณสามารถสร้าง app ที่มี user authentication, เก็บข้อมูล, และ scale ได้จริงโดยไม่ต้องเป็น backend developer
สำหรับ best practices เพิ่มเติมในการ Vibe Code ให้ได้คุณภาพ อ่านได้ที่ Vibe Coding Best Practices — เขียน AI Code ให้ดีและปลอดภัย
ก้าวต่อไป
ถ้าอยากเรียน Vibe Coding แบบมีโครงสร้างและมีอาจารย์คอยแนะนำ:
- Pre-class Setup Guide — เตรียม environment ก่อนเรียน ทำตามได้ทุกคน
- ดูคอร์สและราคา — Gold, Diamond Yearly, และ Diamond Lifetime plan ที่เหมาะกับทุกระดับ
- เรียน AI ที่เชียงใหม่ — AI Unlocked 2026 — Workshop แบบ hands-on สำหรับคนที่อยากเรียนแบบเจอหน้า
- Vibe Coding สำหรับมือใหม่ — เริ่มจาก 0 ใน 1 วัน — ถ้ายังใหม่มากๆ เริ่มที่นี่ก่อน
คำถามหรือข้อสงสัยเพิ่มเติม ทักมาได้ที่ AI Unlocked Community เลย
เขียนโดย
AI Unlocked Team
บทความอื่นๆ ที่น่าสนใจ

AI Agent + RAG — สอนสร้าง Agent ตอบข้อมูลบริษัท
สร้าง AI Agent ด้วย RAG ให้ตอบข้อมูลบริษัทแบบ real-time — ครอบคลุม Architecture, Vector DB, Embeddings, ภาษาไทย Tips พร้อม Code ดู Pricing

คอร์ส AI เชียงใหม่ ที่มีฝึกงาน — สถาบันไหนมีบริการ
หาคอร์ส AI เชียงใหม่ที่มีโปรแกรมฝึกงานจริง เปรียบเทียบรูปแบบ Internship ทักษะที่ต้องเตรียม และวิธี transition สู่งาน Full-time
เรียน AI สำหรับ SME — Roadmap 90 วัน เพิ่มยอดขาย
Roadmap เรียน AI SME ครบ 90 วัน ตั้งแต่ใช้ ChatGPT เป็น จนถึง automate ยอดขาย — เหมาะเจ้าของธุรกิจไทยที่อยากเริ่มได้เลย ไม่ต้องมีพื้นฐาน ดูราคาคอร์ส
