Skip to main content

Supabase vs Appwrite in 2026: Which Open Source BaaS?

·OSSAlt Team
supabaseappwritebaasfirebasecomparison
Share:

Supabase vs Appwrite in 2026: Open Source BaaS Platforms Compared

TL;DR

Both Supabase and Appwrite are open source Firebase replacements with auth, database, storage, and real-time built in. Supabase is built on PostgreSQL — full SQL access, row-level security, vector search, and the largest open source BaaS community. Appwrite is database-agnostic with a document model and 14 function runtimes — more opinionated, but more flexible about language choice for server-side logic. For most developers: Supabase wins on database power and ecosystem. For teams running multi-language functions or preferring a document model: Appwrite makes a strong case.

Key Takeaways

  • Supabase (Apache-2.0, 76K+ stars) is built on PostgreSQL — full SQL, RLS, PostgREST auto-API, pgvector, and database branching
  • Appwrite (BSD-3-Clause, 46K+ stars) uses a document model on MariaDB with 14 function runtimes (Node.js, Python, PHP, Ruby, Go, Swift, Dart, Bun, Deno, and more)
  • Firebase's Blaze plan costs $0.05/GB/month storage + $0.12/GB bandwidth — a growing app pays $200-500+/month
  • Supabase's real-time uses PostgreSQL logical replication (truly database-driven); Appwrite's real-time is event-based through the application layer
  • Appwrite has 12+ client SDKs including more mobile platform SDKs; Supabase has JS, Flutter, Swift, Kotlin, Python
  • Both support 30+ OAuth providers, email/password auth, magic links, and anonymous sessions

The Firebase Replacement Problem

Firebase's problem isn't the product — it's the pricing trajectory. The free Spark plan is genuinely useful, which creates adoption. Then as an app grows, costs become unpredictable: storage at $0.05/GB/month, Firestore reads at $0.06/100K, writes at $0.18/100K, bandwidth at $0.12/GB. A mobile app with 50K daily active users doing moderate database activity can easily hit $300-600/month.

Self-hosted BaaS eliminates per-operation pricing. One VPS costs the same whether you do 1 million or 100 million database reads.

The more interesting question is which self-hosted BaaS fits your architecture.


Supabase — PostgreSQL-Powered BaaS

Supabase makes a bold architectural bet: PostgreSQL is a better foundation for a modern BaaS than Firestore, MongoDB, or DynamoDB. The bet has paid off — Supabase's 76K GitHub stars and significant cloud ARR validate the approach.

The core insight is that PostgreSQL is already a complete platform: full ACID transactions, row-level security, stored procedures, triggers, extensions, full-text search, JSON support, and a rich ecosystem of tools. Supabase builds a developer-friendly layer on top rather than replacing the database.

# Supabase self-hosted (key services)
services:
  db:
    image: supabase/postgres:15.1.0.147
    environment:
      POSTGRES_PASSWORD: your-db-password
    volumes:
      - supabase_db:/var/lib/postgresql/data

  rest:
    image: postgrest/postgrest:v12.0.2
    environment:
      PGRST_DB_URI: postgres://authenticator:password@db:5432/postgres
      PGRST_JWT_SECRET: your-jwt-secret
      PGRST_DB_SCHEMAS: public,storage,extensions

  auth:
    image: supabase/gotrue:v2.140.0
    environment:
      GOTRUE_SITE_URL: https://app.yourdomain.com
      GOTRUE_JWT_SECRET: your-jwt-secret
      DATABASE_URL: postgres://supabase_auth_admin:password@db:5432/postgres
      GOTRUE_SMTP_HOST: smtp.yourdomain.com

  realtime:
    image: supabase/realtime:v2.27.5
    environment:
      DB_HOST: db
      DB_PASSWORD: your-db-password
      JWT_SECRET: your-jwt-secret

  storage:
    image: supabase/storage-api:v0.46.4
    environment:
      PGSQL_CONNECTION_STRING: postgres://supabase_storage_admin:password@db:5432/postgres

  studio:
    image: supabase/studio:20240101-8e4a94c
    ports:
      - "3000:3000"
    environment:
      SUPABASE_URL: http://kong:8000
      SUPABASE_ANON_KEY: your-anon-key

volumes:
  supabase_db:

Row-level security is Supabase's security model — define access rules at the database level using PostgreSQL policies:

-- Enable RLS on the table
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- Users can only read their own posts and all published posts
CREATE POLICY "Read own or published posts"
ON posts FOR SELECT
USING (
  auth.uid() = user_id  -- Own posts
  OR published = true   -- Or any published post
);

-- Only the author can update their posts
CREATE POLICY "Authors can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = user_id);

-- Check user role for admin access
CREATE POLICY "Admins can read everything"
ON posts FOR SELECT
USING (
  (SELECT role FROM user_profiles WHERE id = auth.uid()) = 'admin'
);

The Supabase JavaScript SDK is arguably the best-designed BaaS SDK available:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  'https://db.yourdomain.com',
  'your-anon-key'
);

// Type-safe queries (with TypeScript generated types)
const { data: posts, error } = await supabase
  .from('posts')
  .select(`
    id, title, content, created_at,
    author:users!inner(id, name, avatar_url),
    tags:post_tags(tag:tags(name))
  `)
  .eq('published', true)
  .order('created_at', { ascending: false })
  .limit(20);

// Real-time subscription (WebSocket)
const channel = supabase
  .channel('posts-changes')
  .on('postgres_changes', {
    event: 'INSERT',
    schema: 'public',
    table: 'posts',
    filter: 'published=eq.true',
  }, (payload) => {
    console.log('New post published:', payload.new);
  })
  .subscribe();

// File upload
const { data, error: uploadError } = await supabase.storage
  .from('avatars')
  .upload(`${userId}/avatar.png`, file, {
    contentType: 'image/png',
    upsert: true,
  });

Key features:

  • PostgreSQL with full SQL access
  • Auto-generated REST API (PostgREST) from your database schema
  • Row-level security (database-enforced access control)
  • Real-time via PostgreSQL logical replication
  • Auth: email/password, magic links, phone OTP, 50+ OAuth providers, SSO/SAML
  • File storage (S3-compatible)
  • Edge functions (Deno/TypeScript)
  • Vector search (pgvector)
  • Database branching for dev/staging
  • PostgreSQL extensions (PostGIS, pg_cron, pg_partman, TimescaleDB)
  • SDKs: JavaScript/TypeScript, Flutter, Swift, Kotlin, Python, C#, Go
  • Apache-2.0 license, 76K+ stars

Appwrite — The Multi-Runtime BaaS

Appwrite's architecture makes different tradeoffs: it abstracts the database behind a document API (no direct SQL), but provides far more flexibility in serverless function runtimes. If your team writes backend logic in Python, Ruby, or Swift — not just Node.js and TypeScript — Appwrite's 14 runtimes are a meaningful advantage.

# Appwrite Docker Compose (simplified)
services:
  appwrite:
    image: appwrite/appwrite:1.5.7
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - _APP_ENV=production
      - _APP_LOCALE=en
      - _APP_DOMAIN=api.yourdomain.com
      - _APP_DOMAIN_TARGET=api.yourdomain.com
      - _APP_DB_HOST=appwrite-mariadb
      - _APP_DB_PORT=3306
      - _APP_DB_SCHEMA=appwrite
      - _APP_DB_USER=appwrite
      - _APP_DB_PASS=password
      - _APP_REDIS_HOST=appwrite-redis
      - _APP_SMTP_HOST=smtp.yourdomain.com
      - _APP_SMTP_PORT=587
      - _APP_OPENSSL_KEY_V1=your-encryption-key
      - _APP_JWT_SECRET=your-jwt-secret
    depends_on:
      - appwrite-mariadb
      - appwrite-redis

  appwrite-worker-functions:
    image: appwrite/appwrite:1.5.7
    entrypoint: worker-functions

  appwrite-executor:
    image: openruntimes/executor:0.5.5
    # Executes serverless functions in Docker containers

  appwrite-mariadb:
    image: mariadb:10.11
    volumes:
      - appwrite_mariadb:/var/lib/mysql

  appwrite-redis:
    image: redis:7.2-alpine
    volumes:
      - appwrite_redis:/data

volumes:
  appwrite_mariadb:
  appwrite_redis:

The document model organizes data as collections of documents with typed attributes (string, integer, float, boolean, enum, array, relationship). This is similar to Firebase Firestore — flexible schema, no migrations required for adding fields.

import { Client, Databases, ID } from 'appwrite';

const client = new Client()
  .setEndpoint('https://api.yourdomain.com/v1')
  .setProject('your-project-id');

const databases = new Databases(client);

// Create a document
const post = await databases.createDocument(
  'main-db',     // Database ID
  'posts',       // Collection ID
  ID.unique(),   // Document ID
  {
    title: 'Hello from Appwrite',
    content: 'This is my post content.',
    published: true,
    authorId: currentUser.$id,
  }
);

// Query documents
const posts = await databases.listDocuments('main-db', 'posts', [
  Query.equal('published', true),
  Query.orderDesc('$createdAt'),
  Query.limit(20),
]);

Serverless functions run in isolated Docker containers with 14 available runtimes:

// Appwrite Function (Node.js runtime)
export default async ({ req, res, log, error }) => {
  const { userId } = JSON.parse(req.body);

  // Access other Appwrite services from inside a function
  const client = new Client()
    .setEndpoint(process.env.APPWRITE_ENDPOINT)
    .setProject(process.env.APPWRITE_PROJECT_ID)
    .setKey(process.env.APPWRITE_API_KEY);

  const databases = new Databases(client);
  const user = await databases.getDocument('users-db', 'profiles', userId);

  log(`Processing user: ${user.name}`);

  return res.json({ user, processed: true });
};

Available function runtimes: Node.js, Python, PHP, Ruby, Go, Swift, Dart, Bun, Deno, .NET, Kotlin, Java

Key features:

  • Document model (no direct SQL, flexible schema)
  • 14 function runtimes
  • Auth: email/password, OAuth2, phone/SMS, anonymous, JWT, magic links
  • 30+ OAuth providers
  • File storage with image transformation API
  • Real-time subscriptions (WebSocket)
  • Teams and permission management
  • Webhooks for all events
  • SDKs: 12+ platforms (Web, Flutter, Android, iOS, React Native, Node.js, Python, PHP, Ruby, Go, .NET, Swift)
  • Rate limiting and abuse protection
  • BSD-3-Clause license, 46K+ stars

Side-by-Side Comparison

FeatureSupabaseAppwrite
LicenseApache-2.0BSD-3-Clause
Stars76K+46K+
Database modelPostgreSQL (relational)Document (MariaDB backend)
Direct SQL✅ Full PostgreSQL
Row-level security✅ PostgreSQL RLSCollection-level permissions
Real-timePostgres logical replicationEvent-based WebSocket
Edge functionsDeno (TypeScript)14 runtimes
Vector search✅ pgvector
Database branching
SDK platformsJS, Flutter, Swift, Kotlin, Python12+ platforms including React Native
OAuth providers50+30+
Min RAM (self-hosted)2 GB4 GB
Number of services8+12+

Decision Framework

Choose Supabase if:

  • PostgreSQL's power is important — complex queries, JOINs, stored procedures, extensions
  • Row-level security (database-enforced access control) is a requirement
  • Vector search for AI/semantic features is on the roadmap
  • JavaScript/TypeScript is your primary development language
  • Database branching for dev/staging workflows is valuable
  • You want the largest BaaS community and ecosystem

Choose Appwrite if:

  • You need serverless functions in non-JavaScript languages (Python, Go, Ruby, PHP, Swift)
  • A document model (schemaless, no migrations) fits your mental model better than relational
  • You're building cross-platform apps with React Native or need the full SDK breadth
  • You want a more traditional BaaS experience similar to Firebase Firestore
  • BSD-3-Clause license is preferred over Apache-2.0

Cost Comparison

ScaleFirebase BlazeSupabase Self-HostedAppwrite Self-Hosted
1K MAU~$0$20–30/month$20–30/month
10K MAU~$50/month$20–30/month$30–40/month
100K MAU$200+/month$40–80/month$50–100/month

Related: Best Open Source BaaS Platforms 2026 · Appwrite vs PocketBase · PocketBase vs Supabase

See open source alternatives to Supabase on OSSAlt.

The SaaS-to-Self-Hosted Migration Guide (Free PDF)

Step-by-step: infrastructure setup, data migration, backups, and security for 15+ common SaaS replacements. Used by 300+ developers.

Join 300+ self-hosters. Unsubscribe in one click.