Supabase is a BaaS (Backend as a Service) platform gaining attention as an open-source alternative to Firebase.
Built on PostgreSQL, it provides authentication, storage, serverless functions, and other features.
This post covers getting started with Supabase, basic authentication, database integration, and examples of using storage.
1. Introducing Supabase
1.1 Features
- Open source: core services are open source, providing transparency and extensibility
- PostgreSQL-based: uses the powerful, reliable PostgreSQL database
- Automatic API generation: a RESTful API is available as soon as a table is created
- Authentication and storage: provides authentication, storage, and serverless functions, similar to Firebase
1.2 Differences from Firebase
- License: Firebase is provided by Google, while Supabase is open source and anyone can contribute
- Database: uses SQL-based PostgreSQL, unlike Firebase Realtime Database or Firestore
- Deployment: self-host the community edition or use Supabase's hosting
2. Starting a Project
2.1 Create a Project
First, create an account on the official Supabase site, then create a project.
- Choose a project name
- Select a region
- Set a password
- Once the project is created, you can obtain connection and authentication details such as the API URL and anon/public key.
2.2 Install the Supabase CLI (Optional)
The Supabase CLI makes it easy to manage a project locally.
Install and try it as follows.
npm install supabase --globalAfter installation, run supabase --version to verify it was installed successfully.
3. Integrating Supabase with a Next.js Project
3.1 Create a Next.js Project
npx create-next-app my-supabase-app
cd my-supabase-appAfter creating the project, install the required package.
npm install @supabase/supabase-js3.2 Set Environment Variables
Create .env.local and save the API URL and anon key supplied by Supabase as follows:
NEXT_PUBLIC_SUPABASE_URL=<YOUR_SUPABASE_URL>
NEXT_PUBLIC_SUPABASE_ANON_KEY=<YOUR_SUPABASE_ANON_KEY>3.3 Configure the Supabase Client
Create a shared Supabase client.
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);supabaseUrl: the Supabase project's URLsupabaseAnonKey: the public key (anon key) issued by Supabase- With this code, you can import and use the
supabaseobject anywhere.
4. Trying the Basic Features
4.1 Authentication
Supabase offers several authentication methods, including email/password and social login.
Email/Password Sign-Up Example
import React, { useState } from 'react';
import { supabase } from '../lib/supabaseClient';
export default function AuthPage() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSignUp = async () => {
const { user, error } = await supabase.auth.signUp({
email,
password,
});
if (error) {
console.error('Sign up error: ', error.message);
} else {
console.log('Sign up success: ', user);
}
};
return (
<div>
<h1>회원가입</h1>
<input
type="email"
placeholder="이메일"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="비밀번호"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={handleSignUp}>가입하기</button>
</div>
);
}- Use
supabase.auth.signUp()for email/password registration. - After registration, you can see the user in the Supabase console.
4.2 Database
Create a Data Table
- Create a table in the Supabase console's Table Editor.
- For example, a
todostable - Columns:
id(PK, auto-increment),title, andis_complete(boolean)
- For example, a
Insert and Query Data
import React, { useEffect, useState } from 'react';
import { supabase } from '../lib/supabaseClient';
export default function Todos() {
const [todos, setTodos] = useState([]);
useEffect(() => {
fetchTodos();
}, []);
const fetchTodos = async () => {
const { data, error } = await supabase.from('todos').select('*');
if (error) console.error('Error fetching todos:', error);
else setTodos(data || []);
};
const addTodo = async () => {
const { error } = await supabase.from('todos').insert({ title: 'New Task', is_complete: false });
if (error) console.error('Error adding todo:', error);
else fetchTodos();
};
return (
<div>
<h1>Todos</h1>
<button onClick={addTodo}>할 일 추가</button>
<ul>
{todos.map((todo: any) => (
<li key={todo.id}>
{todo.title} - {todo.is_complete ? '완료' : '미완료'}
</li>
))}
</ul>
</div>
);
}- Query all data in todos with
supabase.from('todos').select('*') - Add a new task with
supabase.from('todos').insert() - If there is no error, update state to reflect the result immediately on screen
4.3 Storage
Storage lets you save files, images, and other uploads from users.
- Create a storage bucket
- In the Supabase console, open Storage → click New Bucket → choose a bucket name, for example
images
- In the Supabase console, open Storage → click New Bucket → choose a bucket name, for example
- Client-Side Upload Example
import React, { useState } from 'react'; import { supabase } from '../lib/supabaseClient'; export default function Upload() { const [selectedFile, setSelectedFile] = useState<File | null>(null); const handleUpload = async () => { if (!selectedFile) return; const { data, error } = await supabase.storage .from('images') .upload(`public/${selectedFile.name}`, selectedFile, { upsert: true, }); if (error) console.error('Upload error: ', error.message); else console.log('Upload success: ', data); }; return ( <div> <h1>이미지 업로드</h1> <input type="file" onChange={(e) => setSelectedFile(e.target.files?.[0] || null)} /> <button onClick={handleUpload}>업로드하기</button> </div> ); }- Use
supabase.storage.from('images')to reference theimagesbucket - A successful upload returns the file path
- Use
5. Using Serverless Functions (Optional)
Supabase lets you implement various backend tasks through serverless functions.
You can create custom APIs or configure cron jobs.
However, serverless functions are currently a beta feature, so testing and stability verification are needed before adopting them in a live service.
6. Debugging and Troubleshooting
-
Authentication Problems
- Check that the authentication method is enabled in the Supabase console, such as social login or email authentication
- Recheck the API key and URL configuration related to
supabase.auth
-
CORS Errors
- Add the domain under Allowed Origins (CORS) in the project settings
-
Database Query Errors
- Test the query directly in the console's Table Editor or SQL Editor
- Check permission policies, since enabled RLS (Row Level Security) may be responsible
7. Considerations for Using Supabase in a Live Service
- Cost: a free plan exists, but increased database usage may incur charges
- Scalability: as the project grows, consider self-hosting and provisioning server resources yourself
- RLS (Row Level Security): Supabase supports fine-grained permission management through RLS, which is enabled by default
- Beta features: serverless functions and Edge features are still in beta, so use them with care
8. Conclusion
Supabase is an open-source solution for building a backend quickly and easily, much like Firebase.
Its use of PostgreSQL offers a substantial advantage to developers familiar with SQL.
With automatically generated RESTful APIs, authentication, and storage, it is well suited to rapid prototyping and running real services.
- Strengths: open source, PostgreSQL-based, and feature-rich
- Weaknesses: some features, such as serverless functions, are in beta; advanced features have a learning curve
- Example uses: hobby projects, MVPs, and startup services
That concludes this introduction to integrating and using Supabase in a project.
For more information, consult the official documentation or the community.





Comments
Korean and English pages share this conversation.
Loading comments…