Ship a sellable full-stack app, not a frontend mockup. Use whenever a build needs real data, accounts, payments, or a live URL — auth, database schema, Row Level Security, file storage, or deploying to production. Stack is Next.js + Supabase (Postgres/Auth/Storage) + Vercel, all on free tiers. Pair with the isekai skill for the UI and the shadcn skill for components.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Ship a sellable full-stack app, not a frontend mockup. Use whenever a build needs real data, accounts, payments, or a live URL — auth, database schema, Row Level Security, file storage, or deploying to production. Stack is Next.js + Supabase (Postgres/Auth/Storage) + Vercel, all on free tiers. Pair with the isekai skill for the UI and the shadcn skill for components.
Isekai Backend — the other half of a $10k build
A beautiful frontend with no real backend is a mockup, not a product. This skill is what turns an isekai build into something a client could actually log into, pay for, and trust with their data. Use it any time a build needs accounts, a database, uploads, or a real deploy — not just "add a backend" requests.
Framework: Next.js App Router, deployed on Vercel's free Hobby tier
Client: @supabase/ssr — the current official package for cookie-based sessions in Next.js. The old auth-helpers-nextjs is deprecated; never scaffold it.
Components: use the shadcn skill for forms, tables, and auth screens instead of hand-rolling markup.
BANNED (the default AI-backend look — never ship any of these)
Row Level Security left off "for now" — the #1 way Supabase side-projects leak every row to anyone with the anon key
service_role key referenced anywhere in a Client Component or a NEXT_PUBLIC_* env var
Secrets committed to the repo with no .env.example for the next person
One Supabase project shared between local dev and production
Forms that write straight to the client SDK with no server-side validation
Tables with no created_at/updated_at, no primary key strategy, or naming that mixes camelCase and snake_case
Auth screens built from scratch when a shadcn block already exists for it
"It works on my machine" — nothing pushed to Vercel, no live URL to hand the client
Process
Design the schema first. List entities and relationships before writing SQL. snake_case tables and columns, id uuid primary key default gen_random_uuid(), created_at timestamptz default now(), updated_at maintained by a trigger. Foreign keys with an explicit on delete policy — don't leave it to default.
Turn on RLS the moment you create the table.alter table public.<table> enable row level security; is not optional and not a later step. Write one policy per operation (select/insert/update/delete) scoped to auth.uid(), not one broad for all policy that overshares.
Wire auth with @supabase/ssr. Server client for Server Components/Route Handlers, browser client for Client Components, middleware to refresh the session on every request. See references/supabase-nextjs.md for the exact client setup.
Mutations go through Server Actions or Route Handlers, never a client-side .insert() on a form submit with no server check. Validate input server-side even if the client already validated it.
Storage buckets get policies too — mirror the same auth.uid() logic as table RLS. Public buckets only for genuinely public assets (avatars, product images); everything else gets signed URLs.
Generate types, don't hand-write them.supabase gen types typescript --project-id <ref> > types/database.ts after every schema change, so the app is type-safe against the real schema.
Two Supabase projects minimum — one for local/preview, one for production. Never point a Vercel Preview deployment at the production database.
Deploy to Vercel. Import the GitHub repo, set env vars per environment (Production/Preview/Development get different Supabase projects), confirm the build succeeds, then click through the live URL like a client would — signup, login, the core flow — before calling it done.
Env vars (know which side of the fence each one is on)
Variable
Exposed to browser?
Where it lives
NEXT_PUBLIC_SUPABASE_URL
Yes
Fine client-side
NEXT_PUBLIC_SUPABASE_ANON_KEY
Yes
Fine client-side — RLS is what actually protects data, not hiding this key
SUPABASE_SERVICE_ROLE_KEY
Never
Server only: Route Handlers, Server Actions, cron/edge functions. Bypasses RLS entirely.
The "sellable" checklist (before calling it done)
RLS enabled on every table in public, policies tested with a non-owner account
Auth flow works end-to-end: signup, login, logout, session persists across refresh
Loading, empty, and error states exist for every data-fetching view — not just the happy path
Form validation happens server-side, not just in the browser
.env.example committed, real .env.local gitignored
Production and preview point at separate Supabase projects
Deployed to Vercel with a working live URL, custom domain connected if the client has one
Spam/abuse protection on public forms (contact, signup) — pair with the turnstile-spin skill if bot traffic is a concern
Basic SEO: page titles, meta description, OG image — a link shared in Slack should look intentional