Pernah nggak sih kamu lagi bikin project sampingan, entah itu aplikasi web atau mobile, terus pas bagian backend malah bingung sendiri? Harus setup server, bikin API, urusan autentikasi, database, belum lagi kalau mau ada fitur upload file. Ribet banget, kan? Apalagi kalau kamu cuma developer solo atau lagi belajar — budget hosting aja kadang mikir dua kali.
Nah, kalau kamu pernah dengar soal Firebase dan merasa “wah, ini solusi banget”, tapi kemudian kaget sama tagihannya setelah scale up — kamu nggak sendirian. Banyak developer yang akhirnya cari alternatif. Dan salah satu nama yang paling sering muncul belakangan ini adalah Supabase.
Aku sendiri udah pakai Supabase di beberapa project, dari yang iseng-iseng sampai yang agak serius. Dan jujur, pengalaman pakainya enak banget. Makanya di tulisan ini, aku mau sharing lengkap cara pakai Supabase untuk tiga kebutuhan utama: autentikasi (Auth), database, dan storage. Semuanya gratis. Nggak ada trik tersembunyi.
Apa Itu Supabase dan Kenapa Kamu Harus Coba?
Sebelum masuk ke tutorial teknisnya, aku mau cerita dulu kenapa Supabase ini menarik.
Supabase itu basically adalah open-source alternatif untuk Firebase. Tapi bedanya, Supabase dibangun di atas PostgreSQL — database relational yang udah terbukti kuat dan dipakai di mana-mana. Jadi kalau kamu udah familiar dengan SQL, kamu bakal langsung nyaman.
Yang bikin Supabase spesial menurutku ada beberapa hal:
- Gratisan yang generous. Paket free tier-nya kasih kamu 500 MB database, 1 GB file storage, 50.000 monthly active users untuk auth, dan 500 MB bandwidth. Buat project kecil-menengah, ini lebih dari cukup.
- Dashboard yang intuitif. Kamu bisa manage database langsung dari browser, kayak phpMyAdmin tapi jauh lebih modern dan clean.
- Built-in Auth. Nggak perlu bikin sistem login dari nol. Supabase udah support email/password, OAuth (Google, GitHub, dll.), bahkan magic link.
- Realtime. Kamu bisa listen perubahan data secara realtime tanpa setup WebSocket sendiri.
- REST API dan Client Library otomatis. Begitu kamu bikin tabel, API-nya langsung jalan. Tinggal pakai.
Kalau kamu terbiasa pakai Firebase tapi pengen coba sesuatu yang lebih “open” dan berbasis SQL, Supabase adalah jawabannya. Kalau kamu belum pernah pakai backend-as-a-service sama sekali, Supabase juga ramah buat pemula.
Oke, sekarang kita mulai dari awal ya.
Mulai dari Nol: Setup Project Supabase
Hal pertama yang perlu kamu lakukan adalah membuat akun dan project di Supabase. Caranya gampang banget:
- Buka supabase.com dan daftar. Kamu bisa pakai akun GitHub, jadi prosesnya cepat.
- Setelah login, klik “New Project”.
- Isi nama project, buat password untuk database (simpan baik-baik!), dan pilih region yang paling dekat. Kalau target pengguna di Asia Tenggara, pilih aja Southeast Asia (Singapore).
- Tunggu sekitar 1-2 menit, dan project kamu siap.
Setelah project jadi, kamu bakal masuk ke dashboard. Di sinilah semua magic terjadi. Kamu akan melihat sidebar dengan menu Table Editor, Authentication, Storage, dan lain-lain.
Yang paling penting: cari Project URL dan anon public key. Kedua ini ada di bagian Settings → API. Kita bakal pakai ini nanti di kode.
Sekarang, install Supabase client library di project JavaScript/TypeScript kamu:
npm install @supabase/supabase-js
Lalu buat file konfigurasi:
// supabaseClient.js
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://xxxx.supabase.co'
const supabaseAnonKey = 'your-anon-key-here'
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
Ganti supabaseUrl dan supabaseAnonKey dengan milikmu. Dan jangan pernah commit anon key ke public repository kalau kamu nggak yakin — walaupun sebenarnya anon key ini memang dirancang untuk dipakai di sisi client, tetap bijak ya.
Menggunakan Supabase Auth: Login Tanpa Ribet
Ini bagian favoritku. Supabase Auth itu chef’s kiss. Kamu bisa dapat sistem autentikasi lengkap dalam hitungan menit, bukan hari.
Registrasi dan Login dengan Email/Password
Cara paling basic adalah email dan password. Begini kode registrasinya:
// Registrasi user baru
async function signUp(email, password) {
const { data, error } = await supabase.auth.signUp({
email: email,
password: password,
})
if (error) {
console.error('Error sign up:', error.message)
return
}
console.log('User berhasil daftar:', data)
}
Dan untuk login:
// Login
async function signIn(email, password) {
const { data, error } = await supabase.auth.signInWithPassword({
email: email,
password: password,
})
if (error) {
console.error('Error login:', error.message)
return
}
console.log('User berhasil login:', data.user)
}
Mudah banget, kan? Nggak perlu bikin endpoint /register, /login, hashing password, generate JWT — semuanya di-handle sama Supabase.
Login dengan OAuth (Google, GitHub, dll.)
Nah, ini yang makin keren. Mau tambahin login pakai Google? Tinggal satu baris:
// Login dengan Google
async function signInWithGoogle() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
})
if (error) {
console.error('Error OAuth:', error.message)
}
}
Supabase support banyak provider: Google, GitHub, GitLab, Discord, Twitter, Facebook, Apple, dan masih banyak lagi. Tinggal aktifkan di dashboard (Authentication → Providers), masukkan Client ID dan Secret dari masing-masing provider, selesai.
Cek Status Login
Mau tahu user lagi login atau nggak? Gampang:
// Cek session saat ini
async function getUser() {
const { data: { user } } = await supabase.auth.getUser()
if (user) {
console.log('User login sebagai:', user.email)
} else {
console.log('Belum login')
}
}
Kamu juga bisa listen perubahan auth state secara realtime:
// Listen perubahan auth state
supabase.auth.onAuthStateChange((event, session) => {
console.log('Auth event:', event) // SIGNED_IN, SIGNED_OUT, dll.
console.log('Session:', session)
})
Fitur ini berguna banget kalau kamu bikin SPA (Single Page Application) dan mau update UI otomatis ketika user login atau logout.
Row Level Security (RLS) — Ini Penting!
Satu hal yang sering dilupakan pemula: Row Level Security. Di Supabase, setiap tabel punya RLS yang harus kamu atur. Tanpa ini, siapa saja bisa akses data kamu.
Caranya, di dashboard buka Table Editor, pilih tabel, lalu klik ikon kecil di sebelah nama tabel untuk mengaktifkan RLS. Kemudian bikin policy. Contoh: “user hanya bisa baca data miliknya sendiri”:
-- Policy: User hanya bisa SELECT data miliknya sendiri
CREATE POLICY "Users can read own data"
ON profiles
FOR SELECT
USING (auth.uid() = user_id);
Atau kalau mau lebih fleksibel, kamu bisa bikin policy untuk INSERT, UPDATE, DELETE juga. Intinya: jangan skip RLS kalau kamu serius soal keamanan.
Database Supabase: PostgreSQL Tanpa Pusing
Supabase memberimu akses penuh ke PostgreSQL. Ini bukan database abal-abal — ini database enterprise-grade yang dipakai oleh perusahaan besar di seluruh dunia. Bedanya, kamu nggak perlu setup server sendiri.
Membuat Tabel via Dashboard
Cara paling gampang buat pemula: pakai Table Editor di dashboard. Klik “New Table”, masukkan nama kolom, tipe data, dan selesai. Kamu bahkan bisa atur primary key, foreign key, dan default value langsung dari UI.
Tapi kalau kamu lebih suka SQL murni (dan aku sarankan ini untuk project serius), buka menu SQL Editor dan jalankan query:
-- Membuat tabel profiles
CREATE TABLE profiles (
id UUID REFERENCES auth.users(id) PRIMARY KEY,
full_name TEXT NOT NULL,
avatar_url TEXT,
bio TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Membuat tabel posts
CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE,
title TEXT NOT NULL,
content TEXT,
published BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CRUD dari JavaScript
Setelah tabel jadi, kamu bisa langsung melakukan operasi CRUD dari kode:
Create (Insert Data):
const { data, error } = await supabase
.from('posts')
.insert([
{
title: 'Postingan Pertama',
content: 'Ini adalah konten postingan pertamaku.',
user_id: 'uuid-user-kamu'
}
])
.select()
Read (Query Data):
// Ambil semua postingan yang sudah dipublish
const { data, error } = await supabase
.from('posts')
.select('*')
.eq('published', true)
.order('created_at', { ascending: false })
.limit(10)
Update:
const { data, error } = await supabase
.from('posts')
.update({ published: true })
.eq('id', 123)
.select()
Delete:
const { error } = await supabase
.from('posts')
.delete()
.eq('id', 123)
Lihat pattern-nya? Konsisten banget, kan? .from('nama_tabel') lalu chaining method. Buat yang pernah pakai ORM seperti Knex atau Prisma, ini terasa familiar.
Filter yang Powerful
Supabase client punya banyak filter built-in yang sangat membantu:
// Filter dengan multiple kondisi
const { data } = await supabase
.from('posts')
.select('*, profiles(full_name)')
.eq('published', true) // WHERE published = true
.ilike('title', '%supabase%') // WHERE title ILIKE '%supabase%'
.gte('created_at', '2025-01-01') // WHERE created_at >= '2025-01-01'
.order('created_at', { ascending: false })
.range(0, 9) // LIMIT 10, OFFSET 0 (pagination)
Perhatikan bagian select('*, profiles(full_name)') — itu namanya join! Supabase otomatis mendeteksi foreign key dan membolehkan kamu mengambil data dari tabel terkait. Ini fitur yang sangat powerful dan menghemat banyak waktu.
Menggunakan RPC (Stored Procedure)
Kadang kamu butuh logic yang lebih kompleks yang nggak bisa di-handle dengan query biasa. Di sinilah stored procedures berguna:
-- Buat fungsi di SQL Editor
CREATE OR REPLACE FUNCTION get_post_count(user_uuid UUID)
RETURNS BIGINT AS $$
SELECT COUNT(*) FROM posts WHERE user_id = user_uuid;
$$ LANGUAGE SQL;
Lalu panggil dari JavaScript:
const { data, error } = await supabase
.rpc('get_post_count', { user_uuid: 'uuid-kamu' })
console.log('Jumlah post:', data)
Storage Supabase: Upload File dengan Mudah
Fitur ketiga yang nggak kalah penting adalah Storage. Kamu bisa upload dan manage file (gambar, dokumen, video, dll.) langsung dari Supabase. Cocok banget buat fitur upload avatar, gambar postingan, atau lampiran dokumen.
Membuat Bucket
Buka menu Storage di dashboard, lalu buat Bucket baru. Anggap bucket itu kayak folder utama. Kamu bisa buat bucket bernama misalnya avatars atau uploads.
Penting: atur access policy bucket. Kalau file-nya publik (misalnya foto profil), aktifkan opsi Public bucket. Kalau privat (misalnya dokumen pribadi), kamu perlu bikin policy akses manual.
Upload File dari JavaScript
// Upload file gambar
async function uploadAvatar(file, userId) {
const filePath = `${userId}/avatar.png`
const { data, error } = await supabase
.storage
.from('avatars')
.upload(filePath, file, {
cacheControl: '3600',
upsert: true // overwrite kalau sudah ada
})
if (error) {
console.error('Upload gagal:', error.message)
return
}
console.log('Upload berhasil:', data)
}
upsert: true di sini penting kalau kamu mau user bisa ganti avatar tanpa bikin file baru setiap kali.
Mendapatkan URL Publik
Setelah file diupload, kamu perlu URL-nya untuk ditampilkan:
function getAvatarUrl(userId) {
const { data } = supabase
.storage
.from('avatars')
.getPublicUrl(`${userId}/avatar.png`)
console.log('URL avatar:', data.publicUrl)
return data.publicUrl
}
URL ini bisa langsung kamu pakai di tag <img> di HTML atau di komponen React/Vue.
Upload dari Input File di Browser
Kalau kamu pakai React, contoh implementasinya kurang lebih begini:
import { useState } from 'react'
import { supabase } from './supabaseClient'
function AvatarUpload({ userId }) {
const [uploading, setUploading] = useState(false)
const handleUpload = async (event) => {
const file = event.target.files[0]
if (!file) return
setUploading(true)
const filePath = `${userId}/avatar.png`
const { error } = await supabase
.storage
.from('avatars')
.upload(filePath, file, { upsert: true })
if (error) {
alert('Upload gagal: ' + error.message)
} else {
alert('Avatar berhasil diupload!')
}
setUploading(false)
}
return (
<div>
<input
type="file"
accept="image/*"
onChange={handleUpload}
disabled={uploading}
/>
{uploading && <p>Uploading...</p>}
</div>
)
}
Menghapus File
async function deleteAvatar(userId) {
const { error } = await supabase
.storage
.from('avatars')
.remove([`${userId}/avatar.png`])
if (error) {
console.error('Hapus gagal:', error.message)
}
}
Tips: Transformasi Gambar
Supabase juga support image transformation langsung dari URL. Jadi kalau kamu mau resize gambar, tinggal tambahin parameter di URL:
Fitur ini sangat berguna untuk mengoptimalkan performa — nggak perlu kirim gambar 4MP ke client kalau yang ditampilkan cuma thumbnail 200x200.
Tips dan Best Practice Setelah Beberapa Bulan Pakai
Setelah pakai Supabase di beberapa project, aku punya beberapa catatan yang mungkin berguna buat kamu:
1. Selalu Aktifkan RLS
Aku nggak bisa cukup menekankan ini. Tanpa RLS, data kamu terbuka lebar. Bayangkan kamu punya tabel orders — tanpa RLS, user A bisa query dan lihat order milik user B. Jadi begitu bikin tabel, langsung aktifkan RLS dan bikin policy-nya.
2. Pakai Database Functions untuk Logic Kompleks
Daripada melakukan banyak query dari client yang bisa lambat dan tidak aman, bikin stored procedure di PostgreSQL. Contoh: fitur transfer saldo. Lebih aman dan konsisten dilakukan di database level.
3. Manfaatkan Database Webhooks dan Edge Functions
Supabase support Edge Functions (serverless functions berbasis Deno) dan Database Webhooks. Ini cocok buat trigger action tertentu, misalnya kirim email notifikasi setelah user mendaftar, atau memanggil API pihak ketiga setelah data berubah.
4. Monitor Penggunaan
Di dashboard Supabase ada menu Usage yang menunjukkan berapa banyak resource yang sudah kamu pakai. Pantau ini secara berkala, terutama kalau project kamu mulai ramai. Paket gratis punya limit, dan lebih baik tahu sebelum kehabisan daripada kaget.
5. Backup Database
Di paket Pro, Supabase kasih automatic backup harian. Tapi di paket gratis, kamu perlu manual. Minimal, secara berkala export schema dan data penting kamu. Caranya bisa lewat pg_dump atau cukup lewat dashboard (Database → Backups).
6. Jangan Simpan Secret di Client Code
Walaupun anon key memang dirancang untuk dipakai di client, service role key JANGAN PERNAH kamu expose. Service role key bisa bypass semua RLS dan bisa dipakai untuk aksi admin. Simpan ini di server-side saja, atau pakai environment variable yang aman.
Kapan Supabase Kurang Cocok?
Supabase memang keren, tapi bukan berarti sempurna untuk semua kasus. Berikut beberapa situasi di mana kamu mungkin perlu mempertimbangkan opsi lain:
- Project yang sangat sederhana — Kalau cuma butuh satu atau dua tabel dengan data statis, mungkin Firebase Realtime Database atau bahkan JSON file di GitHub Pages sudah cukup.
- Butuh GraphQL native — Supabase fokus di REST API. Kalau kamu butuh GraphQL, kamu perlu setup tambahan (atau pakai Hasura sebagai alternatif).
- Scale sangat besar dengan traffic tinggi — Paket gratis tentu ada limitnya. Kalau kamu sudah di tahap ini, berarti saatnya upgrade ke Pro atau bahkan self-host Supabase (yang memungkinkan karena open-source!).
Kesimpulan
Supabase benar-benar game changer, terutama buat solo developer dan tim kecil yang mau build produk tanpa pusing urusan infrastruktur. Dengan satu platform, kamu dapat autentikasi lengkap, database PostgreSQL powerful, dan storage untuk file — semuanya gratis untuk memulai.
Yang paling aku suka dari Supabase adalah filosofinya: memberikan developer tools yang biasanya hanya tersedia di perusahaan besar, tapi dalam paket yang mudah diakses semua orang. Kamu nggak perlu jadi DevOps engineer untuk punya backend yang solid.
Kalau kamu belum pernah coba, aku sangat sarankan untuk langsung praktek. Buka supabase.com, buat project baru, ikuti langkah-langkah di tulisan ini, dan lihat sendiri betapa mudahnya. Dalam satu sore, kamu bisa punya aplikasi yang bisa registrasi, login, menyimpan data, dan upload file.
Dan kalau kamu butuh bantuan setup Supabase untuk project kamu, atau mau diskusi soal arsitektur backend yang tepat — jangan ragu buat hubungi aku.
Punya pertanyaan atau butuh bantuan implementasi Supabase di project-mu? Kirim email ke [email protected] — aku senang bisa bantu diskusi teknis atau bahkan kolaborasi bareng.
FAQ (Pertanyaan yang Sering Ditanya)
Apakah Supabase benar-benar gratis untuk selamanya?
Supabase punya paket gratis (Free Plan) yang sangat generous dan bisa kamu pakai selamanya. Tapi tentu ada limitnya: 500 MB database, 1 GB storage, 50.000 monthly active users untuk auth, dan 500 GB bandwidth per bulan. Untuk project side, prototyping, atau bahkan MVP yang belum terlalu ramai, ini lebih dari cukup. Kalau sudah melebihi limit, kamu bisa upgrade ke Pro ($25/bulan) atau bahkan self-host Supabase secara gratis karena project-nya open-source.
Apakah Supabase lebih baik daripada Firebase?
Jawabannya tergantung kebutuhan. Kalau kamu lebih nyaman dengan SQL dan ingin data yang relational, Supabase jelas lebih cocok. PostgreSQL juga lebih powerful untuk query kompleks. Kalau kamu butuh ekosistem lengkap (analytics, A/B testing, messaging, dll.) dan nggak masalah pakai NoSQL, Firebase masih lebih matang. Yang pasti, Supabase lebih transparan (open-source), lebih mudah dipindahkan (karena basisnya PostgreSQL standard), dan pricing-nya lebih terprediksi dibanding Firebase yang bisa bikin kaget tagihannya.
Bisakah Supabase dipakai untuk aplikasi mobile (React Native, Flutter)?
Bisa banget! Supabase punya client library untuk JavaScript/TypeScript (yang bisa dipakai di React Native), Dart (untuk Flutter), Python, Kotlin, Swift, dan bahkan C#. Untuk Flutter, ada package supabase_flutter yang sangat mature. Untuk React Native, kamu bisa langsung pakai @supabase/supabase-js karena React Native berbasis JavaScript. Integrasi OAuth di mobile juga didukung dengan baik melalui deep linking.
Bagaimana cara migrasi dari Firebase ke Supabase?
Supabase menyediakan tool resmi bernama Firebase Migration Tool yang bisa membantu memindahkan data dari Firestore/Realtime Database ke PostgreSQL. Untuk Auth, kamu bisa import user data. Namun perlu diingat: struktur data di Firebase (NoSQL) dan PostgreSQL (SQL) itu berbeda, jadi kamu perlu sedikit redesign schema. Prosesnya nggak instant, tapi banyak komunitas yang sudah berbagi pengalaman migrasi di forum Supabase dan GitHub.
Apakah data di Supabase aman?
Secara umum, ya. Supabase menggunakan enkripsi at rest dan in transit (HTTPS). Kamu juga bisa mengaktifkan Point-in-Time Recovery di paket Pro. Yang paling penting dari sisi keamanan adalah Row Level Security (RLS) yang kamu atur sendiri. Kalau kamu mengaktifkan RLS dengan policy yang benar, data user akan terisolasi dengan baik. Supabase juga sudah SOC2 Type 2 compliant, yang artinya mereka memenuhi standar keamanan industri.