Supabase: o backend que faltava pro React
O problema que o Supabase resolve
Dev frontend que precisa de backend tem historicamente três opções ruins pra MVP:
Montar servidor do zero (Express/Fastify + PostgreSQL). Funciona, mas leva semanas só de setup: configurar auth, modelar banco, criar migrations, setup de storage, configurar WebSocket pra realtime. Tempo que deveria ir pra feature vai pra infraestrutura.
Usar Firebase. Setup rápido, mas vendor lock-in pesado. O banco é NoSQL (Firestore), que complica queries complexas. Quer fazer JOIN? Boa sorte. Quer migrar pra outro lugar depois? Boa sorte também. E o pricing em escala pode surpreender.
Contratar dev backend. Caro, nem sempre necessário pra escala inicial, e adiciona complexidade de coordenação (frontend esperando endpoint, backend esperando tela).
Supabase é a quarta opção: PostgreSQL real com auth, storage, realtime e edge functions num único serviço. Eu testei Firebase e PlanetScale antes. Supabase foi o que encaixou melhor entre controle e produtividade.
A diferença principal: Supabase é PostgreSQL. Não é abstração, não é banco proprietário. Se um dia eu precisar migrar, exporto o banco e levo pra qualquer PostgreSQL do mundo. Sem vendor lock-in.
Na prática, isso significa que qualquer ferramenta que funciona com PostgreSQL funciona com Supabase. Posso conectar pgAdmin, DBeaver, ou qualquer client SQL direto no banco. Posso rodar pg_dump e ter um backup local em minutos. Não fico refém de formato proprietário nem de API que pode mudar sem aviso.
O que vem no pacote
Auth
Registro, login com email/senha, social login (Google, GitHub, Apple), magic link e MFA. Funciona com poucas linhas de código no frontend.
No AutoPars, são 3 perfis (comprador, vendedor, admin) todos gerenciados pelo Supabase Auth. Cada perfil tem role customizado no banco que determina o que pode ver e fazer. O auth vai além de “logou ou não logou”. Importa quem logou e o que essa pessoa pode acessar.
No FitPlan, são 6 perfis (proprietário da rede, diretoria, admin, personal, nutricionista, aluno). Mesmo sistema de auth, mesma estrutura de roles. Escala sem mudar a arquitetura.
Database
PostgreSQL real. SQL puro, views, functions, triggers, indexes. Se você sabe PostgreSQL, sabe usar o banco do Supabase. Não tem linguagem proprietária, não tem abstração que esconde o que tá acontecendo.
O painel do Supabase tem editor SQL integrado, visualização de tabelas, e um query explorer. Pra quem gosta de GUI, é produtivo. Pra quem prefere código, as migrations funcionam como em qualquer PostgreSQL.
Posso criar views que calculam métricas do dashboard do AutoPars (GMV total, receita da plataforma, vendedores ativos) direto no banco. A query roda no PostgreSQL, não no frontend. Performance melhor, menos código no React.
Triggers e functions no banco também resolvem lógica que normalmente ficaria no backend. No AutoPars, quando um pedido é criado, uma function calcula automaticamente a comissão da plataforma e grava o valor na tabela de transações. Isso roda direto no PostgreSQL, não depende de chamada extra do frontend nem de edge function.
Storage
Upload de arquivos com controle de acesso via policies. É o S3 da AWS, mas integrado com o auth e o banco.
No AutoPars, vendedores sobem fotos de peças. Cada vendedor só vê e edita as próprias imagens. Essa regra não tá no código do React, tá no Supabase Storage via policy. Mesmo que tenha um bug no frontend que tente acessar imagem de outro vendedor, o storage bloqueia.
Realtime
WebSockets nativos. Quando um dado muda no banco, o frontend é notificado automaticamente. Sem polling, sem refresh manual, sem configurar Socket.io.
No AutoPars, quando um pedido muda de status (confirmado, em preparo, enviado), o dashboard do admin atualiza sozinho. O admin não precisa dar F5. O vendedor é notificado em tempo real quando recebe uma venda.
No FitPlan, quando o personal marca um treino como concluído, o painel do aluno atualiza instantaneamente.
Edge Functions
Funções serverless em Deno pra lógica que não pode rodar no frontend. Validação de webhook (o Asaas manda POST e você precisa processar no servidor), chamada a API externa com token secreto (não pode expor token no browser), processamento pesado que travaria o cliente.
No AutoPars, o webhook do Asaas chega numa Edge Function que valida a assinatura, processa o evento e atualiza o banco. Tudo server-side, sem expor lógica ou tokens no frontend.
RLS: a parte que mais me convenceu
Row Level Security é o diferencial real do Supabase pra mim. Em vez de validar permissões no código do frontend ou numa camada de API middleware, defino policies direto no PostgreSQL.
Como funciona
Exemplo simplificado: vendedor só vê seus próprios produtos.
CREATE POLICY "vendedor_ve_seus_produtos"
ON products FOR SELECT
USING (seller_id = auth.uid());
auth.uid() retorna o ID do usuário logado automaticamente. Se o vendedor A tenta listar produtos, o PostgreSQL filtra e retorna só os produtos onde seller_id bate com o ID dele. O vendedor B recebe só os dele. Admin tem outra policy que retorna tudo.
Por que isso é melhor que validar no código
A segurança fica no nível mais baixo possível. Mesmo que tenha um bug no frontend que tente SELECT * FROM products, o banco filtra. O dado não sai do PostgreSQL sem passar pela policy. Não depende do React, não depende de middleware, não depende de nada que roda no browser.
É declarativo. A policy diz “vendedor vê só o dele”. Não preciso escrever if (user.role === 'seller' && product.seller_id === user.id) em cada query, em cada endpoint, em cada controller. Uma policy, aplica em tudo.
E é difícil de esquecer. Se eu esquecer de adicionar WHERE seller_id = ? numa query, o dado vaza. Com RLS, a policy aplica automaticamente em toda query naquela tabela. Não tem como esquecer, o banco não deixa.
No AutoPars, cada tabela tem policies pra cada perfil. Comprador vê produtos ativos de todos os vendedores. Vendedor vê e edita só os próprios. Admin vê tudo. São umas 20 policies no total. Declarativas no banco, zero lógica de permissão espalhada pelo código React.
Outro ponto: RLS funciona em toda operação, não só SELECT. Posso definir policies pra INSERT, UPDATE e DELETE separadamente. Vendedor pode inserir produto novo (INSERT), editar os próprios (UPDATE com filtro no seller_id), mas não pode deletar produto que já teve venda (DELETE bloqueado por policy que checa se existe pedido vinculado). Tudo isso sem uma linha de validação no React.
Minha stack com Supabase
Frontend: React + TypeScript + Tailwind
Backend: Supabase (Auth + PostgreSQL + Storage + Realtime)
Deploy: Vercel (frontend) + Supabase Cloud (backend)
Essa combinação me permite entregar webapp completo trabalhando solo. O Mariah saiu em 4 horas. O AutoPars com 5 integrações em semanas, não meses. O Supabase elimina a necessidade de montar servidor, configurar auth, gerenciar uploads e implementar WebSocket. Tudo já vem pronto e integrado.
A produtividade de um dev solo com essa stack compete com time de 2-3 devs usando stack tradicional (Express + PostgreSQL manual + JWT + S3 + Socket.io). Não porque a stack é mágica, mas porque elimina semanas de setup que não geram valor pro cliente.
Quando Supabase não é a melhor escolha
Seria desonesto dizer que Supabase serve pra tudo. Não serve.
Projeto que precisa de backend muito customizado: processamento pesado de dados, filas com prioridade (Bull/BullMQ), workers de longa duração, pipelines de dados complexos. Edge Functions são limitadas em tempo de execução e recursos. Pra isso, precisa de servidor dedicado.
Sistema que já tem banco de dados rodando. Se a empresa já tem PostgreSQL na AWS com 5 anos de dados, schemas complexos e equipe de DBA, não faz sentido migrar pra Supabase. Conecta o React direto no banco existente via API customizada.
Equipe que não sabe SQL. O Supabase é PostgreSQL. Se ninguém no time manja de SQL, vai ter dificuldade com migrations, policies RLS e queries de dashboard. O painel visual ajuda, mas não substitui fundamento em SQL.
Multi-region. Supabase roda num datacenter por projeto. Se precisa de banco replicado em múltiplas regiões pra latência baixa globalmente, precisa de solução mais robusta (CockroachDB, PlanetScale, ou PostgreSQL com replicação manual).
Custo
O plano gratuito aguenta bastante: 50k requests/mês, 500 MB de banco, 1 GB de storage, 500 MB de bandwidth. Pra MVP em validação, sobra.
O plano Pro (US$ 25/mês) é o que uso em produção. Inclui backups diários automáticos, 8 GB de banco, 100 GB de storage e suporte a mais conexões simultâneas. É o que roda no AutoPars e no FitPlan.
Comparado com manter VPS + Nginx + Express + PostgreSQL + gerenciar certificado SSL + backups manuais + monitoramento, US$ 25/mês é barato. E o tempo que eu gastaria mantendo infraestrutura é tempo que gasto desenvolvendo features pro cliente.
Pra escala de preço de um sistema completo, o Supabase como backend reduz o investimento do cliente porque reduz meu tempo de desenvolvimento. Backend que levaria 3-4 semanas pra montar do zero leva 2-3 dias no Supabase.
E se o projeto crescer e ultrapassar os limites do plano Pro, o próximo tier (Team, US$ 599/mês) entra quando a operação já tá faturando o suficiente pra cobrir. Nunca tive projeto que precisou sair do Pro nos primeiros 12 meses. O plano gratuito serve pra validar, o Pro serve pra operar, e a migração entre eles é um clique no painel, sem downtime.