antrix.dev
Ship Your Product · $79

Database with Supabase

Set up your database, authentication, and file storage with Supabase. PostgreSQL under the hood, generous free tier.

Reading this alone?

Do it with peers — bi-weekly calls, $29/mo founding.

Join →

What it does

Supabaseis your database, authentication, file storage, and real-time subscriptions — all in one service. It's PostgreSQL under the hood, which means you get a real, battle-tested relational database with full SQL support. Not a proprietary abstraction that locks you in.

The dashboard lets you manage everything visually — create tables, write queries, manage users, configure storage buckets, and set up security policies. The client library gives your app direct database access with built-in auth handling. You get a complete backend without writing a single line of backend code.

Why we use it

Supabase is the Firebase alternative that doesn't lock you in. Your data lives in a standard PostgreSQL database that you can export, migrate, or connect to from any tool. If you ever outgrow Supabase, you take your data with you.

The free tier is genuinely generous: 500MB database storage, 1GB file storage, 50,000 monthly active users, and unlimited API requests. For most solo products, you'll run for months (or longer) without paying a cent.

Row Level Securityis the key feature that makes this stack work. RLS lets you write security rules directly in the database — so you can safely query from the client without building an entire API layer. The anon key in your client code is safe to expose because RLS prevents unauthorized access at the database level.

Setup checklist

1

Create a Supabase account

Go to supabase.com and sign up with GitHub. Click New Project, give it a name, and set a strong database password— save this somewhere safe, you'll need it if you ever connect directly via psql or a database tool.

Choose a region close to your users. US East (Virginia) works well for North American audiences. EU West (Ireland) for European. Pick the same region as your Vercel deployment for the lowest latency between your app and your database.

2

Get your project credentials

Go to Settings > API in your project dashboard. You need two values: NEXT_PUBLIC_SUPABASE_URL (your project URL, looks like https://abcdefg.supabase.co) and NEXT_PUBLIC_SUPABASE_ANON_KEY (your public anonymous key).

The anon key is safe to expose in client-side code — it's designed to be public. It only grants access that your RLS policies allow. The service_role key, on the other hand, bypasses all RLS. That one is a secret and must never appear in client code.

Add both values to your .env.local for local development and to your Vercel environment variables for production. The NEXT_PUBLIC_ prefix is required for Next.js to make them available in client-side code.

3

Install the Supabase client

Run npm install @supabase/supabase-js. Then create a client file that you'll import throughout your app. This client handles all communication with your Supabase project — database queries, auth, storage, and real-time subscriptions.

4

Design your database schema

Use the Table Editor in the dashboard for quick visual prototyping, or write SQL directly in the SQL Editor. Start with your core tables — the 3-5 tables that represent the fundamental data your app needs.

Think about relationships: a user has many projects, a project has many tasks. Use foreign keys to enforce these relationships. Add a user_idcolumn to any table where you need to know who owns the data — you'll need this for RLS policies.

Don't over-design. You can always add columns and tables later. For an MVP, simpler is better. You don't need junction tables, polymorphic associations, or complex inheritance hierarchies. You need tables that store the data your users create.

5

Set up Row Level Security (RLS)

This is non-negotiable. Enable RLS on every single table. Without it, anyone who has your anon key (which is in your client-side JavaScript, so everyone) can read and write every row in your database.

For each table, create policies that answer these questions: Who can read rows? Who can insert new rows? Who can update existing rows? Who can delete rows? The most common pattern is: users can only access their own data.

A basic policy looks like: auth.uid() = user_id. This checks that the logged-in user's ID matches the user_id column on the row. Apply this to SELECT, INSERT, UPDATE, and DELETE operations. Test every policy in the SQL Editor by running queries as different users.

For public-facing data (like a blog or product listings), create a SELECT policy that allows access to everyone: true as the condition. But keep INSERT, UPDATE, and DELETE restricted to the data owner or admin users.

6

Create your first migration

Install the Supabase CLI and initialize your project: npx supabase init. Then capture your current schema as a migration file: npx supabase db diff --schema public -f create_tables. This generates a SQL file in supabase/migrations/ that can recreate your schema from scratch.

Migrations are version-controlled SQL. They're the source of truth for your database structure. When you change your schema, create a new migration — don't edit old ones. This ensures your changes are reproducible across local development, staging, and production.

Commit your migration files to Git. They should be treated like code — reviewed, versioned, and deployed through your normal workflow.

7

Set up local development

Run npx supabase start to spin up a local Supabase instance. This requires Docker— install Docker Desktop if you don't have it. The local instance includes a Postgres database, Auth server, Storage, and a local dashboard at localhost:54323.

Your local instance starts with the same schema as your migrations. Use npx supabase db reset to wipe local data and re-run all migrations from scratch. This is useful when you want a clean slate or when testing new migrations.

Develop against local, deploy to production. This keeps your production data safe and lets you experiment freely. Update your .env.local to point at the local instance URLs that supabase start outputs.

8

Connect to your Next.js app

For client-side operations (reading public data, user-specific queries with RLS), use the Supabase client you created with the anon key. RLS ensures users only see their own data.

For server-sideoperations (API routes, Server Actions) that need to bypass RLS — like admin operations or processing webhooks — create a separate client using the service_role key. Store the service role key in SUPABASE_SERVICE_ROLE_KEY(no NEXT_PUBLIC_ prefix) so it's only available server-side.

Never import or use the service role client in any component or code that runs in the browser. If your service role key leaks, anyone can read and write your entire database with no restrictions.

9

Set up authentication (if needed)

Supabase Auth supports multiple providers out of the box: email/password, magic links, Google OAuth, GitHub OAuth, and more. Enable the ones you need in Authentication > Providers in your dashboard.

The client library gives you supabase.auth.signUp(), signInWithPassword(), and signInWithOAuth(). For OAuth providers, you'll need to create an app in the provider's developer console (Google Cloud Console, GitHub Settings) and add the client ID and secret to your Supabase dashboard.

Configure your redirect URLsin Authentication > URL Configuration. Set your site URL to your production domain and add any additional redirect URLs for local development (like http://localhost:3000). Without correct redirect URLs, OAuth flows will fail silently.

10

Set up storage (if needed)

Go to Storage in your dashboard and create a new bucket. Buckets can be public (anyone can download files via URL) or private (requires authentication). Use public for profile images and assets. Use private for user documents and uploads.

Upload files from your app using supabase.storage.from('bucket-name').upload('path/file.jpg', file). Storage has its own security policies, just like RLS for tables. Create policies to control who can upload, download, and delete files in each bucket.

For images, Supabase provides automatic transformations — resize, crop, and format conversion via URL parameters. This means you can upload one high-resolution image and serve optimized versions without any processing on your end.

11

Deploy migrations to production

Link your local project to your remote Supabase project: npx supabase link --project-ref YOUR_PROJECT_REF. You'll find your project ref in Settings > General in the dashboard.

Push your migrations to production: npx supabase db push. This applies any new migration files that haven't been run on the remote database yet. Always test migrations locally first using npx supabase db reset before pushing to production.

Make this part of your deploy workflow: write the migration locally, test it with a reset, commit the migration file, push to GitHub, then run db push to apply it to production. Schema changes should never be made by clicking around in the production dashboard.

Sample client setup

// lib/supabase.ts
import { createClient } from "@supabase/supabase-js";
import type { Database } from "@/types/supabase";

export const supabase = createClient<Database>(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

Generate your Database type with: npx supabase gen types typescript --project-id YOUR_REF > types/supabase.ts

Pro tips

Use Supabase's TypeScript generation to get type-safe database queries. Run npx supabase gen types typescript --linked > types/supabase.ts to generate types from your schema. Pass them to createClient<Database>() and your queries will autocomplete column names and catch type errors at build time.

The SQL Editorin the dashboard is your best debugging tool. When a query isn't returning what you expect, run it directly in the SQL Editor to see the raw results. You can also test RLS policies by switching between user contexts.

For complex queries that don't map cleanly to the client library's API, create a database function (stored procedure) and call it with supabase.rpc('function_name', params). This keeps complex logic in SQL where it's fast, and gives you a clean interface from your app.

Set up database webhooks or Postgres triggers for side effects. When a new user signs up, automatically create their profile row. When an order is placed, update inventory counts. Let the database handle cascading logic instead of coordinating it in application code.

AI prompt to get started

I'm building [describe your app]. Help me design the Supabase database schema. I need tables for [describe your data]. For each table, give me: the CREATE TABLE SQL, RLS policies for authenticated users, and the TypeScript types I should use in my app.

Mistakes to avoid

  • Skipping Row Level Security — this is a security disaster waiting to happen. Enable RLS on every table, no exceptions. Without it, your entire database is publicly readable and writable
  • Using the service role key in client-side code — this bypasses all RLS and gives full database access. Only use it in server-side code (API routes, Server Actions). If it leaks, your data is exposed
  • Not using migrations — clicking around in the dashboard works until you need to reproduce your schema in another environment or roll back a change. Migrations are version-controlled truth
  • Hardcoding the Supabase URL or keys — use environment variables. This is not optional. Hardcoded values break across environments and risk committing secrets to Git
  • Over-designing the schema upfront — start with 3-5 tables that cover your core data model. Add complexity as you learn what your users actually need, not what you imagine they might need
  • Not testing RLS policies — use the SQL Editor to run queries as different user contexts before shipping. A policy that looks correct can have subtle holes that expose data

Reading this and want to actually do it with others?

The community is bi-weekly live calls, async accountability, and a group of builders shipping in parallel. Founding seats are $29/mo.

The Community — Coming Soon

For AI-first operators who actually build the thing.

Builders, consultants, founders, freelancers — anyone whose income comes from shipping real work, not from selling courses about shipping.

AI isn't going to make you money. Products do. Clients do. Real businesses do. But AI is the unfair advantage — when you wire it into how you build, sell, and serve, you move 10x faster than people still doing it by hand.

Who it's for

Beginners

Learning AI from people actually using it, not just teaching it.

Builders

Ready to automate workflows — yours or your clients'.

Operators

Senior, deep in production, looking for peers and leverage.

You have real skills. You want AI as an unfair advantage on real work — building something of your own, leveling up at your job, or both — not another set of videos to watch.

What's inside

Direct access — me + the network

Bi-weekly Google Meet calls where we actually work. DMs and posts with me and other operators when you're mid-build and stuck.

  • Bi-weekly live calls — builds, Q&A, teardowns
  • Architecture + payment reviews on your code
  • Peer network of operators who actually ship
  • Paid client referrals when I'm overbooked

The production agentic stack

Everything I run on real client work and my own products — installed in your environment, not just shown in a video.

  • Antrix OS — the control room for your agent fleet
  • Installers: Ship Your Product + Run the Machine
  • ax-* skill packs (audit, deliver, simplify, content, more)
  • Multi-agent code review across parallel worktrees
  • Scheduled jobs, overnight pipelines, dual-AI planning
  • Setup library: Stripe, Supabase, Vercel, Resend

Antrix OS — the agent dashboard

Antrix OS — agent fleet dashboard

The control room I actually run my work from — every project, agent, skill, schedule, machine, and secret in one place. Members get the codebase.

Why this one is different

Most hosts make content.
I make products.

The platform doesn't matter — Skool, Circle, Discord, Whop, whatever. The problem is the host.

Most paid-community founders aren't shipping anything outside of the community itself. Their whole business is selling you the community.

I'm in production every day. The people I want next to me are too.

We level up together.

Most communities

  • Revenue IS the membership fee
  • Main output: content about the community
  • You learn from someone who only sells communities
  • Growth metric: new members

This community

  • Revenue is client work + products. Community is a side of it.
  • Main output: shipped code, deployed products, served clients
  • You learn from someone in production every single day
  • Growth metric: what members are actually shipping

Waitlist

Open · first cohort

Get in before the price moves.

Founding pricing exists for the first cohort. When it fills, the next one pays more — and joins behind it. Names get pulled in order.

  • Founding price locked: $29/mo
  • Bi-weekly live calls + brainstorms
  • Direct access: me + operator peers

Work with me directly

Senior engineering, paired with agentic AI.

I take a handful of clients each quarter. Direct work on your codebase, your stack, your business. No agency. No junior handoffs. You hire me, you get me.

I build with you

Pair sessions where we ship the product, the agent, or the integration that's been blocking you.

I wire AI into your business

Agentic workflows, multi-agent pipelines, and scheduled jobs that turn AI from a chat window into 10x leverage on actual revenue work.

I review what you shipped

Architecture, AI usage, payments. I'll tell you what's worth keeping, what to rip out, and what to ship next.

I set you up, you take it from there

Sometimes you don't need me to run it. You need someone in the room while you do. I'll show you the system.

Specialty — payments

Hundreds of millions processed across subscriptions, marketplaces, and migrations. If your product touches money, that's where I help most. Webhook reliability, marketplace splits, billing architectures — the kind of work where shipping wrong costs you money, not just time.

Tell me what you're building.

I reply within 24 hours.