Development··6 min read

Supabase로 풀스택 앱 만들기 후기

Firebase 대신 Supabase를 선택해서 풀스택 앱을 만든 솔직한 경험담.

Firebase에서 복잡한 쿼리를 짜다가 화가 났다

Firebase를 3년 썼다. 빠르게 프로토타이핑하기엔 최고다. 근데 프로젝트가 커지면서 불만이 쌓였다. NoSQL이라 복잡한 쿼리가 어려웠고, 데이터 마이그레이션이 고통스러웠고, 벤더 락인이 신경 쓰였다.

그러다 Supabase를 발견했다. PostgreSQL 기반이라 SQL을 쓸 수 있고, 오픈소스라 필요하면 셀프 호스팅도 가능하다. "Firebase의 오픈소스 대안"이라는 슬로건에 끌렸다.

사내 도구에 먼저 적용해봤다

직원들이 장비 대여 현황을 관리하는 간단한 앱을 만들어야 했다. Next.js + Supabase 조합으로 시작했다.

프로젝트 생성부터 DB 테이블 설계까지 Supabase 대시보드에서 30분 만에 끝났다. 테이블 에디터가 스프레드시트처럼 직관적이었다. 외래 키 관계도 클릭 몇 번으로 설정할 수 있었다.

인증이 진짜 편하다

Supabase Auth는 내가 써본 인증 솔루션 중 가장 편했다. 구글 로그인 연동이 환경 변수 2개 설정하면 끝이다. 이전에 Passport.js로 직접 구현할 때 반나절 걸렸던 작업이다.

Row Level Security랑 조합하면 API 레벨 인증 로직을 거의 작성하지 않아도 된다. "이 테이블은 로그인한 사용자만 읽기 가능, 자기 데이터만 수정 가능" 같은 정책을 SQL로 정의하면 Supabase가 알아서 적용한다.

(이거 처음 적용했을 때 진심 감동받았다.)

SQL이 되니까 세상이 다르다

Firebase에서 "사용자별 최근 대여 기록을 가져오되, 반납하지 않은 것만 필터링하고, 대여일 기준 내림차순 정렬" 이걸 하려면 코드가 복잡해졌다.

Supabase에서는 SQL 한 줄이면 된다. 클라이언트의 쿼리 빌더도 직관적이다. .from('rentals').select('*, equipment(*)').eq('user_id', userId).is('returned_at', null).order('created_at', { ascending: false }). 거의 SQL 그대로다.

근데 실시간 기능은 좀 아쉽다

Firebase의 실시간 동기화에 익숙했던 나에게 Supabase의 Realtime은 좀 아쉬웠다. 작동은 하는데 연결이 가끔 끊기고, 재연결 로직을 직접 관리해야 했다.

대여 현황을 실시간으로 업데이트해야 하는 화면이 있었는데, 가끔 이벤트가 누락됐다. 결국 30초 주기 폴링과 Realtime을 병행하는 방식으로 타협했다. 실시간 기능이 핵심인 앱이라면 Firebase가 아직은 나을 수 있다.

Edge Functions는 발전 중

서버 로직이 필요한 부분은 Supabase Edge Functions를 사용했다. Deno 기반이라 TypeScript를 바로 쓸 수 있는 건 좋았다. 근데 로컬 개발 환경 설정이 좀 번거로웠고, 디버깅이 불편했다.

간단한 웹훅 처리나 외부 API 호출 정도는 괜찮지만, 복잡한 비즈니스 로직은 별도 백엔드를 두는 게 나을 것 같다.

비용은 예측 가능하다

프리 티어가 넉넉하다. DB 500MB, Auth 사용자 5만 명, 스토리지 1GB. 우리 앱은 사용자가 50명 정도인데 6개월째 무료 티어 안에서 돌아가고 있다.

프로 요금제가 월 25달러인데, Firebase의 Blaze 요금제랑 비교하면 예측 가능한 비용이라는 점이 좋다. Firebase는 사용량 기반이라 갑자기 비용이 튀는 경우가 있었다.

SQL을 아는 개발자라면

Supabase는 SQL을 알고 있는 개발자를 위한 Firebase다. 관계형 데이터를 다루는 앱이라면 Firebase보다 생산적이다. 반대로 실시간 동기화가 핵심이거나 비관계형 데이터를 다룬다면 Firebase가 여전히 좋다.

나는 새 프로젝트를 시작할 때 기본적으로 Supabase를 먼저 고려한다.

관련 글