Development··3 min read

Building a Full-Stack App with Supabase: An Honest Review

A candid experience report on choosing Supabase over Firebase for a full-stack app.

I Got Frustrated Writing Complex Queries in Firebase

I used Firebase for 3 years. For quick prototyping, it's the best. But as projects grew, frustrations piled up. Complex queries were painful with NoSQL, data migration was agonizing, and vendor lock-in kept nagging at me.

Then I found Supabase. PostgreSQL under the hood means I can use SQL. It's open-source, so self-hosting is an option. The tagline "The open-source Firebase alternative" got me.

I Tried It on an Internal Tool First

I needed to build a simple app for employees to manage equipment rentals. Started with Next.js + Supabase.

From project creation to DB schema design, everything was done in the Supabase dashboard in 30 minutes. The table editor felt as intuitive as a spreadsheet. Foreign key relationships could be set up in a few clicks.

Authentication Is Genuinely Effortless

Supabase Auth is the most convenient auth solution I've used. Google login integration? Two environment variables and you're done. That same thing used to take half a day with Passport.js.

Combined with Row Level Security, you barely need to write any API-level auth logic. Define policies in SQL like "this table is readable only by logged-in users, and users can only modify their own data," and Supabase enforces it automatically.

(I was genuinely impressed the first time I got this working.)

Having SQL Changes Everything

In Firebase, "get recent rental records per user, but only unreturned ones, sorted by rental date descending" required convoluted code.

In Supabase, it's one SQL statement. The client query builder is intuitive too: .from('rentals').select('*, equipment(*)').eq('user_id', userId).is('returned_at', null).order('created_at', { ascending: false }). It reads almost like raw SQL.

Real-Time Is a Bit Lacking Though

Coming from Firebase's real-time sync, Supabase's Realtime was a bit disappointing. It works, but the connection occasionally drops, and you have to manage reconnection logic yourself.

We had a screen that needed to show rental status in real time, and events were occasionally missed. We ended up combining Realtime with 30-second polling as a compromise. If real-time is the core of your app, Firebase might still be the better choice.

Edge Functions Are Still Maturing

For server-side logic, I used Supabase Edge Functions. Being Deno-based means you can write TypeScript natively, which is nice. But local dev setup was a bit cumbersome, and debugging was inconvenient.

Fine for simple webhook handling or external API calls, but for complex business logic, a dedicated backend is probably better.

Costs Are Predictable

The free tier is generous. 500MB database, 50,000 auth users, 1GB storage. Our app has about 50 users, and we've been running within the free tier for six months.

The Pro plan is $25/month, and compared to Firebase's Blaze plan, the predictability is a plus. Firebase's usage-based billing occasionally produced surprise spikes.

If You Know SQL

Supabase is Firebase for developers who know SQL. If your app deals with relational data, Supabase is more productive than Firebase. Conversely, if real-time sync is essential or you're working with non-relational data, Firebase is still a strong pick.

For new projects, I now default to considering Supabase first.

Related Posts