ANTIGRAVITY LABJP
Articles/Integrations
Integrations/2026-04-04Advanced

Building on Antigravity and Supabase — Auth, RLS, Edge Functions, and the 4-Second Query That Taught Me Policy Performance

Implementation patterns for shipping production apps with Antigravity and Supabase — Auth, RLS, Edge Functions, and Realtime — plus why enabling RLS can make queries crawl, how to measure and fix it, and where solo-dev costs actually break.

supabase7antigravity444authrlsedge-functionsrealtime4fullstack5production71

Premium Article

The morning after I enabled RLS, a list query took four seconds

When I moved the backend of one of my side projects onto Supabase, the thing that tripped me up first wasn't auth, and it wasn't storage. It was RLS. The morning after I enabled row-level security on every table, a list query that used to return in about 80ms was taking nearly four seconds — on local test data.

The policies were written exactly as the Supabase docs describe. The indexes were there. It was still slow. It took me the better part of a day, staring at EXPLAIN ANALYZE output, to find out why.

Supabase is a genuinely well-built foundation: PostgreSQL at the core, with auth, storage, Edge Functions, and Realtime layered on top. As an indie developer shipping apps on the App Store and Google Play alongside a day's other work, it lifts a weight that's hard to carry alone. Pair it with Antigravity and you can move from schema design to RLS policy generation to Edge Function code without losing the thread of your project's context.

But whether that generated code survives production is a separate question. There's a real distance between a policy that works and a policy that's both fast and safe.

This article walks the full set of implementation patterns — Auth, RLS, Edge Functions, Realtime, Storage — and then covers the two judgment calls I actually had to make to close that distance: policy performance, and the point where a solo project's costs start to move. Where those four seconds went is answered after Chapter 3.


Chapter 1: Project Setup and Antigravity Initial Configuration

Preparing Your Supabase Project

Start by installing the Supabase CLI and setting up a local development environment. Run the following in Antigravity's terminal:

# Install Supabase CLI
npm install supabase --save-dev
 
# Initialize the project
npx supabase init
 
# Start local Supabase (requires Docker)
npx supabase start

After startup, you'll see output like this:

Started supabase local development setup.

         API URL: http://127.0.0.1:54321
     GraphQL URL: http://127.0.0.1:54321/graphql/v1
  S3 Storage URL: http://127.0.0.1:54321/storage/v1/s3
          DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
      Studio URL: http://127.0.0.1:54323
    Inbucket URL: http://127.0.0.1:54324
      JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
        anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Configuring Antigravity's RULES.md

Set up your RULES.md (or .antigravity/rules.md) so Antigravity can accurately understand your project context:

# Project Rules
 
## Tech Stack
- Next.js 15+ App Router
- Supabase (PostgreSQL + Auth + Storage + Realtime)
- TypeScript (strict mode)
- Tailwind CSS
 
## Supabase Conventions
- Table names: snake_case (plural)
- Column names: snake_case
- RLS must be enabled on all tables
- service_role key is server-side only
 
## Security Rules
- Client-side code uses anon key only
- All user data access must be controlled by RLS
- service_role is only used inside Edge Functions

With this configuration, Antigravity will automatically apply security best practices during code generation.

Setting Up the TypeScript Client

// lib/supabase/client.ts — for client components
import { createBrowserClient } from '@supabase/ssr'
import type { Database } from '@/types/supabase'
 
export function createClient() {
  return createBrowserClient<Database>(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}
 
// lib/supabase/server.ts — for server components and Server Actions
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
import type { Database } from '@/types/supabase'
 
export async function createClient() {
  const cookieStore = await cookies()
  return createServerClient<Database>(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options)
            )
          } catch {
            // Safe to ignore when called from Server Components
          }
        },
      },
    }
  )
}

By keeping these files in view, Antigravity will correctly choose the right client in all subsequent code generation.


Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Diagnose why enabling RLS tanks query latency, then fix it by hoisting auth.uid() into an InitPlan — measured with EXPLAIN ANALYZE, before and after
Write multi-tenant RLS policies that cross-reference tables without hitting infinite recursion, using a properly locked-down security definer function
Estimate where a solo project actually outgrows the Supabase free tier — egress and Realtime connections bite long before row count does
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

Integrations2026-04-21
Building Production-Grade Voice Agents with Gemini Live API in Antigravity — Bidirectional Audio, Screen Share, and Latency Patterns
A field guide for shipping production-ready realtime voice agents with Gemini Live API on Antigravity. Covers architecture, latency, resilience, function calling, and cost governance with working TypeScript.
App Dev2026-03-28
Building Real-Time Full-Stack Apps with Antigravity and Supabase: A Practical Guide
Learn how to combine Antigravity IDE with Supabase to build full-stack apps featuring authentication, database management, and real-time sync — step by step.
Integrations2026-05-15
Using Claude Opus 4 / Sonnet 4 in Antigravity — Model Selection Strategy and Production Patterns
A practical guide to using Claude Opus 4, Sonnet 4, and Haiku 4.5 in Antigravity. Learn the decision framework and production implementation patterns for balancing cost, speed, and quality in real projects.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →