Week 3 · Data & backend · Lesson 15
Supabase: what it is, and why people reach for it
A managed Postgres database with auth, storage, realtime, and edge functions bolted on — built so a small team can skip writing most of a backend by hand.
1. What Supabase actually is
Supabase is a hosted platform built around a real PostgreSQL database. Every project you create gets a full Postgres instance — not a proprietary abstraction on top of one — and Supabase wraps it with the handful of services almost every application ends up needing anyway: user authentication, file storage, realtime subscriptions to data changes, and serverless edge functions.
It's usually described as "the open-source Firebase alternative", which is a fair shorthand: it targets the same job (give a small team a backend without hand-rolling one) but swaps Firebase's proprietary NoSQL document store for a standard relational database you could, in principle, export and run anywhere.
2. Why it exists / why people use it
Before tools like this existed, shipping even a simple app with logins and a database meant standing up a database server, an auth service (or rolling your own password hashing and session handling), a place to store uploaded files, and — if you wanted live updates — a WebSocket layer on top of all of it. That's a lot of infrastructure before you've written a single line of actual product logic.
Supabase's pitch is to collapse all of that into one dashboard and one client library: createClient(), then call .from('table').select(), .auth.signIn(), or .storage.upload() and the backend is already there. For solo developers, small teams, and early-stage products, that trade of "some flexibility" for "weeks of setup time saved" is usually a clear win.
3. What's under the hood
The reason Supabase can move this fast without turning into a black box is that almost every piece is a well-known open-source project, glued together rather than reinvented:
- Database: stock PostgreSQL — the same engine covered in Lesson 14, with all its extensions (including
pgvector for embeddings) available.
- Auth: a dedicated auth service that issues JWTs and integrates directly with Postgres row-level security (RLS), so access rules live as policies on the database itself instead of scattered across application code.
- Storage: S3-compatible object storage with a CDN in front, for files and uploads, governed by the same RLS policies as the database.
- Realtime: a layer that listens to Postgres's write-ahead log and pushes changes to subscribed clients over WebSockets — live updates without polling.
- Edge Functions: small serverless functions (Deno-based) for logic that shouldn't live in the client, like calling a third-party API with a secret key.
The one feature people mention most: generated TypeScript types straight from your database schema. Every table and column becomes a real type in your code, so a schema change surfaces as a type error at build time instead of a runtime surprise in production.
4. Pros
What it gets right
- Real Postgres underneath — you keep access to the full SQL feature set, extensions, and a well-known query language instead of a proprietary data model.
- Auth, storage, and realtime are already wired together and enforce the same permission model (RLS), instead of three separate services with three separate access-control systems to keep in sync.
- Open-source core, with a documented path to self-host the entire stack if you ever need to leave the managed service — genuinely lower lock-in than most "backend-as-a-service" competitors.
- A generous free tier and predictable paid plans make it realistic to start a side project without committing to real spend on day one.
5. Cons
Where it gets uncomfortable
- Row-level security is powerful but has a real learning curve — writing correct RLS policies is closer to writing small pieces of application logic in SQL than flipping a switch, and getting one wrong quietly leaks or blocks data.
- Because everything is layered on one Postgres instance, very large or unusual scaling needs (extreme write throughput, multi-region active-active) eventually run into limits that a purpose-built combination of separate services might not.
- Vendor dependency in practice is lower than most alternatives but not zero — self-hosting the full stack (Auth, Storage, Realtime, Studio) is possible but meaningfully more operational work than just using the managed product.
- Edge Functions run on Deno, which is a smaller ecosystem than Node's — some npm packages need workarounds or aren't available at all.
6. Compared to the alternatives
| Option | Core model | Best fit | Watch out for |
| Supabase | Managed Postgres + bundled services | Teams that want a relational database and are fine writing SQL-flavored access rules | RLS learning curve; Deno-based functions |
| Firebase | Proprietary NoSQL (Firestore) + bundled services | Mobile-first apps, teams that prefer a document model over relational tables | No SQL, heavier vendor lock-in, harder to self-host or migrate away from |
| Roll your own (Postgres + Auth0/Clerk + S3 + a WebSocket server) | Separate best-in-class services, wired together yourself | Teams with specific requirements each piece must meet individually, or that need to swap one piece later without touching the rest | Real integration work; nothing enforces one shared permission model across the pieces |
| PocketBase | Single-binary SQLite-backed backend, auth + realtime built in | Small projects, self-hosted personal tools, situations where "one binary, no cloud dependency" matters more than scale | SQLite's single-writer limits (Lesson 13) apply; smaller ecosystem than Supabase's |
7. A practical example
Picture a small internal tool: a form where employees submit expense reports, with a manager who needs to see and approve them. With Supabase, the whole backend for that tool looks roughly like this:
- One
expenses table in Postgres, with columns for amount, description, status, and the submitting user's ID.
- Two RLS policies: one letting each user read/insert only their own rows, another letting anyone with a
role = 'manager' claim read and update any row.
- Auth handles the login screen and issues the JWT that carries the user's ID and role into every request.
- Storage holds the uploaded receipt images, with a policy mirroring the same "own rows only, unless you're a manager" rule.
- A Realtime subscription on the manager's dashboard means a new submission shows up instantly, with no manual refresh or polling.
None of that requires writing a dedicated auth server, a file upload endpoint, or a notifications system — it's mostly table design and a couple of SQL policies, which is exactly the class of problem Supabase is built to shrink.
8. How to actually decide
Reach for Supabase when: the project needs a relational database anyway, the team is comfortable with (or willing to learn) SQL-based access rules, and shipping fast matters more than having every service be independently swappable.
Reach for Firebase instead when: the data genuinely fits a document/NoSQL shape better than tables, or the team is mobile-first and already deep in Google's ecosystem (FCM push notifications, Crashlytics, etc.).
Roll your own instead when: the project has a real requirement one specific service must satisfy (a particular auth provider mandated by a client, a storage provider already paid for at the company level) that a bundled platform can't flex around.
For most small-to-medium products starting from zero today, Supabase is a reasonable default: it gives up very little relative to assembling the pieces by hand, and the underlying Postgres means the "what if I outgrow this" question has a real answer instead of a rewrite.
Semana 3 · Dados e backend · Lição 15
Supabase: o que é, e por que as pessoas usam
Um Postgres gerenciado com auth, storage, realtime e edge functions acoplados — feito pra um time pequeno pular a parte de escrever a maior parte de um backend na mão.
1. O que é o Supabase de fato
O Supabase é uma plataforma hospedada construída em volta de um PostgreSQL de verdade. Todo projeto que você cria recebe uma instância Postgres completa — não uma abstração proprietária em cima de um — e o Supabase envolve isso com o punhado de serviços que quase toda aplicação acaba precisando de qualquer forma: autenticação de usuário, armazenamento de arquivos, assinaturas em tempo real de mudanças nos dados, e funções serverless na edge.
Geralmente é descrito como "a alternativa open-source ao Firebase", o que é um resumo justo: ele tem o mesmo objetivo (dar a um time pequeno um backend sem construir um na mão) mas troca o banco de documentos NoSQL proprietário do Firebase por um banco relacional padrão que você poderia, em teoria, exportar e rodar em qualquer lugar.
2. Por que existe / por que as pessoas usam
Antes de ferramentas como essa existirem, lançar até um app simples com login e banco de dados significava montar um servidor de banco, um serviço de auth (ou fazer você mesmo o hash de senha e a gestão de sessão), um lugar pra guardar arquivos enviados e, se você quisesse atualizações em tempo real, uma camada WebSocket em cima de tudo isso. Isso é muita infraestrutura antes de você escrever uma linha de lógica de produto de fato.
A proposta do Supabase é colapsar tudo isso num painel só e numa biblioteca de cliente só: createClient(), e depois .from('tabela').select(), .auth.signIn() ou .storage.upload() e o backend já está lá. Pra devs solo, times pequenos e produtos em estágio inicial, essa troca de "um pouco de flexibilidade" por "semanas de configuração economizadas" costuma ser uma vitória clara.
3. O que tem por debaixo do capô
O motivo do Supabase conseguir andar tão rápido sem virar uma caixa preta é que quase toda peça é um projeto open-source conhecido, colado nos outros em vez de reinventado:
- Banco de dados: PostgreSQL padrão — o mesmo motor visto na Lição 14, com todas as suas extensões disponíveis (incluindo
pgvector pra embeddings).
- Auth: um serviço de autenticação dedicado que emite JWTs e se integra direto com row-level security (RLS) do Postgres, então as regras de acesso vivem como políticas no próprio banco em vez de espalhadas pelo código da aplicação.
- Storage: armazenamento de objetos compatível com S3, com CDN na frente, pra arquivos e uploads, governado pelas mesmas políticas de RLS do banco.
- Realtime: uma camada que escuta o write-ahead log do Postgres e envia mudanças pros clientes inscritos via WebSockets — atualizações em tempo real sem polling.
- Edge Functions: funções serverless pequenas (baseadas em Deno) pra lógica que não deveria viver no cliente, como chamar uma API de terceiro com uma chave secreta.
O recurso mais citado: tipos TypeScript gerados direto do esquema do seu banco. Cada tabela e coluna vira um tipo real no seu código, então uma mudança de esquema aparece como erro de compilação em vez de surpresa em produção.
4. Prós
O que ele acerta
- Postgres de verdade por debaixo — você mantém acesso a todo o conjunto de recursos SQL, extensões e uma linguagem de query bem conhecida, em vez de um modelo de dados proprietário.
- Auth, storage e realtime já vêm conectados e aplicam o mesmo modelo de permissão (RLS), em vez de três serviços separados com três sistemas de controle de acesso separados pra manter sincronizados.
- Núcleo open-source, com um caminho documentado pra auto-hospedar a stack inteira se você um dia precisar sair do serviço gerenciado — lock-in genuinamente menor que a maioria dos concorrentes de "backend-as-a-service".
- Um plano gratuito generoso e planos pagos previsíveis tornam realista começar um projeto paralelo sem se comprometer com gasto real no primeiro dia.
5. Contras
Onde fica desconfortável
- Row-level security é poderoso mas tem uma curva de aprendizado real — escrever políticas de RLS corretas é mais parecido com escrever pequenos pedaços de lógica de aplicação em SQL do que apertar um botão, e errar uma silenciosamente vaza ou bloqueia dados.
- Como tudo fica em camadas sobre uma instância Postgres só, necessidades de escala muito grandes ou fora do comum (throughput de escrita extremo, multi-região ativo-ativo) eventualmente batem em limites que uma combinação de serviços separados feita sob medida talvez não bata.
- Dependência de fornecedor na prática é menor que a maioria das alternativas mas não é zero — auto-hospedar a stack inteira (Auth, Storage, Realtime, Studio) é possível mas dá bem mais trabalho operacional do que simplesmente usar o produto gerenciado.
- Edge Functions rodam em Deno, um ecossistema menor que o do Node — alguns pacotes npm precisam de contornos ou simplesmente não estão disponíveis.
6. Comparado às alternativas
| Opção | Modelo central | Melhor encaixe | Atenção a |
| Supabase | Postgres gerenciado + serviços empacotados | Times que querem um banco relacional e não têm problema em escrever regras de acesso em estilo SQL | Curva de aprendizado do RLS; funções baseadas em Deno |
| Firebase | NoSQL proprietário (Firestore) + serviços empacotados | Apps mobile-first, times que preferem um modelo de documento a tabelas relacionais | Sem SQL, lock-in de fornecedor mais pesado, mais difícil de auto-hospedar ou migrar |
| Fazer na mão (Postgres + Auth0/Clerk + S3 + um servidor WebSocket) | Serviços separados, cada um o melhor da categoria, conectados por você | Times com requisitos específicos que cada peça precisa cumprir individualmente, ou que precisam trocar uma peça depois sem tocar no resto | Trabalho de integração de verdade; nada aplica um modelo de permissão único compartilhado entre as peças |
| PocketBase | Backend de binário único baseado em SQLite, com auth + realtime embutidos | Projetos pequenos, ferramentas pessoais auto-hospedadas, situações onde "um binário só, sem dependência de nuvem" importa mais que escala | Os limites de escritor único do SQLite (Lição 13) se aplicam; ecossistema menor que o do Supabase |
7. Um exemplo prático
Imagine uma ferramenta interna pequena: um formulário onde funcionários enviam relatórios de despesas, com um gestor que precisa ver e aprovar cada um. Com o Supabase, o backend inteiro dessa ferramenta fica mais ou menos assim:
- Uma tabela
despesas no Postgres, com colunas pra valor, descrição, status e o ID do usuário que enviou.
- Duas políticas de RLS: uma deixando cada usuário ler/inserir só as próprias linhas, outra deixando qualquer um com
role = 'gestor' ler e atualizar qualquer linha.
- O Auth cuida da tela de login e emite o JWT que leva o ID e o papel do usuário pra cada requisição.
- O Storage guarda as imagens de recibo enviadas, com uma política espelhando a mesma regra "só as próprias linhas, a menos que seja gestor".
- Uma assinatura Realtime no painel do gestor faz um novo envio aparecer instantaneamente, sem refresh manual nem polling.
Nada disso exige escrever um servidor de auth dedicado, um endpoint de upload de arquivo ou um sistema de notificações — é majoritariamente design de tabela e um par de políticas SQL, exatamente a classe de problema que o Supabase foi feito pra encolher.
8. Como decidir, na prática
Use o Supabase quando: o projeto precisa de um banco relacional de qualquer forma, o time está confortável (ou dispensado a aprender) regras de acesso baseadas em SQL, e lançar rápido importa mais que ter cada serviço independentemente trocável.
Use o Firebase no lugar quando: os dados de fato se encaixam melhor num formato de documento/NoSQL do que em tabelas, ou o time é mobile-first e já está profundo no ecossistema do Google (notificações push via FCM, Crashlytics, etc.).
Faça na mão no lugar quando: o projeto tem um requisito real que um serviço específico precisa cumprir (um provedor de auth específico exigido por um cliente, um provedor de storage já pago no nível da empresa) que uma plataforma empacotada não consegue flexibilizar.
Pra maioria dos produtos pequenos e médios começando do zero hoje, o Supabase é um padrão razoável: ele cede muito pouco em relação a montar as peças na mão, e o Postgres por debaixo faz a pergunta "e se eu crescer demais pra isso" ter uma resposta real em vez de uma reescrita.