Supabase Starter vs Firebase Starter vs Appwrite Starter 2026
·StarterPick Team
supabasefirebaseappwritebaassaas-boilerplatedatabase2026
TL;DR
Supabase has won the developer mindshare race for SaaS in 2026. PostgreSQL (real SQL, not NoSQL), Row Level Security, built-in auth, storage, edge functions — all in one platform with a generous free tier. Firebase is still dominant in mobile-first and consumer apps (Firebase Cloud Messaging, Crashlytics, Google Analytics integration). Appwrite is the open-source self-hosted alternative for teams with data sovereignty requirements. For most SaaS startups in 2026: Supabase starter is the path of least resistance.
Key Takeaways
- Supabase: Postgres, RLS, auth, storage, realtime, edge functions — open source, free 500MB DB
- Firebase: Firestore (NoSQL), Firebase Auth, FCM push, Crashlytics, real-time by default, Google-owned
- Appwrite: Self-hosted BaaS, Postgres database, auth, storage, messaging — full control
- SQL vs NoSQL: Supabase = real SQL (relational); Firebase = document store (flexible but costly at scale)
- Pricing break-even: Supabase free tier lasts longer for most SaaS; Firebase costs grow faster with reads
- Best for SaaS: Supabase (SQL + RLS = great for multi-tenant)
Supabase Starter
Official Next.js Starter
# Official Supabase Next.js starter:
npx create-next-app -e with-supabase my-app
# Or:
git clone https://github.com/vercel/next.js/tree/canary/examples/with-supabase
Core Patterns
// lib/supabase/server.ts:
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function createClient() {
const cookieStore = await cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll: () => cookieStore.getAll(),
setAll: (cookiesToSet) => {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
);
} catch {}
},
},
}
);
}
// Row Level Security — multi-tenant security in SQL:
// SQL migration:
CREATE TABLE projects (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
user_id UUID REFERENCES auth.users(id) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Enable RLS:
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
-- Users can only see their own projects:
CREATE POLICY "Users see own projects" ON projects
FOR ALL USING (auth.uid() = user_id);
// Query respects RLS automatically:
const supabase = await createClient();
const { data: projects } = await supabase
.from('projects')
.select('*');
// Only returns the current user's projects — RLS enforced by Postgres
// Supabase Auth in Next.js App Router:
import { redirect } from 'next/navigation';
import { createClient } from '@/lib/supabase/server';
export default async function DashboardPage() {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) redirect('/login');
const { data: projects } = await supabase.from('projects').select('*');
return <ProjectList projects={projects ?? []} />;
}
Supabase Pricing
Free tier:
→ 500MB PostgreSQL
→ 1GB storage
→ 2GB bandwidth
→ 50,000 monthly active users
→ Pause after 1 week inactivity
Pro: $25/month
→ 8GB PostgreSQL
→ 100GB storage
→ 250GB bandwidth
→ Unlimited MAU
→ No pause
Firebase Starter
npm install firebase
npx firebase init
// lib/firebase.ts:
import { initializeApp, getApps } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';
import { getStorage } from 'firebase/storage';
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY!,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN!,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET!,
};
const app = getApps().length ? getApps()[0]! : initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const auth = getAuth(app);
export const storage = getStorage(app);
// Firestore real-time subscription:
import { collection, onSnapshot, query, where, orderBy } from 'firebase/firestore';
import { db } from '@/lib/firebase';
export function useUserProjects(userId: string) {
const [projects, setProjects] = useState<Project[]>([]);
useEffect(() => {
const q = query(
collection(db, 'projects'),
where('userId', '==', userId),
orderBy('createdAt', 'desc')
);
// Real-time listener (Firebase's superpower):
const unsubscribe = onSnapshot(q, (snapshot) => {
const docs = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
setProjects(docs as Project[]);
});
return unsubscribe; // Cleanup
}, [userId]);
return projects;
}
Firebase Pricing Reality
Spark (free):
→ 1GB Firestore storage
→ 50K reads/day, 20K writes/day, 20K deletes/day
→ 10GB bandwidth
→ CRITICAL: limits reset DAILY — easy to hit in prod
Blaze (pay as you go):
→ Firestore: $0.06/100K reads, $0.18/100K writes
→ A SaaS with 1000 DAU doing 50 reads/session = 1.5M reads/day
→ Cost: 1,500,000 / 100,000 * $0.06 = ~$90/day ← WATCH OUT
Firebase cost optimization requires aggressive Firestore read minimization.
Appwrite Starter
# Self-hosted (Docker):
docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.5.0
# Or use Appwrite Cloud (managed):
npm install appwrite
// lib/appwrite.ts:
import { Client, Account, Databases, Storage } from 'appwrite';
const client = new Client()
.setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID!);
export const account = new Account(client);
export const databases = new Databases(client);
export const storage = new Storage(client);
// Appwrite database query:
import { databases, Query } from '@/lib/appwrite';
const projects = await databases.listDocuments(
'my-database-id',
'projects',
[
Query.equal('userId', userId),
Query.orderDesc('$createdAt'),
Query.limit(10),
]
);
Appwrite Pricing
Free (cloud):
→ 75K monthly active users
→ 2GB storage
→ 300GB bandwidth
→ Unlimited databases
Pro: $15/member/month
→ Everything unlimited (within fair use)
Self-hosted: Free forever
→ Your infrastructure costs only
→ Full data control
Comparison Table
| Supabase | Firebase | Appwrite | |
|---|---|---|---|
| Database | PostgreSQL (SQL) | Firestore (NoSQL) | MariaDB (SQL-like) |
| Auth | ✅ | ✅ | ✅ |
| Real-time | ✅ | ✅ (core feature) | ✅ |
| Storage | ✅ | ✅ | ✅ |
| Edge functions | ✅ Deno | Cloud Functions | ✅ |
| Self-hosted | ✅ | ❌ | ✅ |
| SQL queries | ✅ Full Postgres | ❌ | Partial |
| Row-level security | ✅ RLS | Rules-based | Permissions |
| Free tier DB | 500MB | 1GB | 2GB |
| Pricing predictability | High | Low (reads add up) | High |
Decision Guide
Choose Supabase if:
→ SaaS with relational data (users, orgs, subscriptions)
→ Need SQL querying power
→ Multi-tenancy via Row Level Security
→ TypeScript + Prisma or Drizzle ecosystem
Choose Firebase if:
→ Mobile-first consumer app (Firebase + Flutter/React Native)
→ Need Firebase Cloud Messaging for push notifications
→ Real-time sync is a core feature (chat, collaborative)
→ Already in Google Cloud ecosystem
Choose Appwrite if:
→ Data sovereignty (self-hosted required)
→ GDPR compliance needs local hosting
→ Open source stack only
→ Developer tools or internal apps with budget constraints
Compare Supabase, Firebase, and Appwrite starters at StarterPick.