# Supabase

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-iwritec0de-app-dev-supabase`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [iwritec0de](https://agentstack.voostack.com/s/iwritec0de)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [iwritec0de](https://github.com/iwritec0de)
- **Source:** https://github.com/iwritec0de/app-dev/tree/main/skills/supabase

## Install

```sh
agentstack add skill-iwritec0de-app-dev-supabase
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Supabase Skill

You are a Supabase expert for Next.js applications using the App Router.

## Critical Rules

- **Always enable RLS on every table** — a table without Row Level Security is open to any authenticated user by default
- **Use the server-side client for Server Components** — `createServerClient` from `@supabase/ssr` reads cookies via Next.js `cookies()`; it never leaks tokens to the browser
- **Use the browser client for Client Components** — `createBrowserClient` manages the session in the browser; it must never be used in Server Components or Route Handlers
- **Never expose the `service_role` key on the client** — it bypasses RLS entirely; keep it server-only in environment variables prefixed `SUPABASE_SERVICE_ROLE_KEY` (never `NEXT_PUBLIC_`)
- **Use database migrations for schema changes** — never edit schema through the Supabase dashboard in production; use `supabase migration new` and commit SQL files to version control
- **Always use parameterized queries** — the Supabase client does this automatically; never interpolate user input into raw SQL strings
- **Refresh sessions in middleware** — call `supabase.auth.getUser()` in `middleware.ts` on every request to keep the session cookie fresh

## Client Setup

Install the required packages:

```bash
npm install @supabase/supabase-js @supabase/ssr
```

**Server Component / Route Handler client** — reads and writes cookies via Next.js `cookies()`:

```ts
// lib/supabase/server.ts
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(
    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 in Server Components; middleware handles refresh
        },
      },
    }
  )
}
```

**Client Component client** — manages the session in the browser:

```ts
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'
import type { Database } from '@/types/supabase'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}
```

Read `reference/auth-patterns.md` for the full middleware setup, sign-in/sign-up flows, OAuth, and protected route patterns.

## Database

Always import your generated types for full type safety:

```ts
import type { Database } from '@/types/supabase'
// Generate: npx supabase gen types typescript --local > types/supabase.ts
```

Common query patterns:

```ts
const supabase = await createClient()

// Select with filter
const { data, error } = await supabase
  .from('posts')
  .select('id, title, created_at')
  .eq('user_id', userId)
  .order('created_at', { ascending: false })

// Insert
const { data, error } = await supabase
  .from('posts')
  .insert({ title, body, user_id: userId })
  .select()
  .single()

// Upsert
const { error } = await supabase
  .from('profiles')
  .upsert({ id: userId, display_name: name })
```

Read `reference/database-patterns.md` for RLS policy patterns, migrations, RPC functions, joins, and views.

## RLS Policies — Quick Reference

```sql
-- Authenticated users can read all rows
CREATE POLICY "authenticated read" ON posts
  FOR SELECT TO authenticated USING (true);

-- Users can only modify their own rows
CREATE POLICY "owner write" ON posts
  FOR ALL TO authenticated USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

-- Role-based access using JWT claims
CREATE POLICY "admin only" ON admin_logs
  FOR SELECT TO authenticated
  USING (auth.jwt() ->> 'role' = 'admin');
```

Read `reference/database-patterns.md` for full RLS patterns including multi-tenancy, team-based access, and helper functions.

## Storage

```ts
// Upload a file
const { data, error } = await supabase.storage
  .from('avatars')
  .upload(`${userId}/avatar.png`, file, { upsert: true })

// Get a public URL (public bucket)
const { data: { publicUrl } } = supabase.storage
  .from('avatars')
  .getPublicUrl(`${userId}/avatar.png`)

// Get a signed URL (private bucket, expires in 60 seconds)
const { data, error } = await supabase.storage
  .from('documents')
  .createSignedUrl(`${userId}/file.pdf`, 60)
```

Read `reference/realtime-storage.md` for image transformations, resumable uploads, and storage RLS.

## Realtime

```ts
'use client'
// Subscribe to table changes
const channel = supabase
  .channel('posts-changes')
  .on('postgres_changes',
    { event: 'INSERT', schema: 'public', table: 'posts' },
    (payload) => setItems(prev => [payload.new as Post, ...prev])
  )
  .subscribe()

return () => { supabase.removeChannel(channel) }
```

Read `reference/realtime-storage.md` for presence, broadcast, and channel cleanup patterns.

## Anti-Patterns

- **Do not disable RLS** — even temporarily; attackers do not wait for you to re-enable it
- **Do not use `service_role` on the client** — it bypasses all security policies; it belongs only in trusted server environments
- **Do not skip migrations** — dashboard edits to schema are not tracked in version control and will diverge between environments
- **Do not store auth state in localStorage** — the `@supabase/ssr` client handles sessions via HttpOnly cookies; localStorage is not accessible server-side and is vulnerable to XSS
- **Do not call `getSession()` on the server** — use `getUser()` instead; `getSession()` does not revalidate the token against the Supabase server
- **Do not use `createClient` from `@supabase/supabase-js` in Next.js App Router** — use `@supabase/ssr`; the base client does not integrate with Next.js cookie handling

## Related

- `reference/auth-patterns.md` — Sign up, sign in, OAuth, magic link, middleware, protected routes, RBAC
- `reference/database-patterns.md` — Schema design, RLS policies, migrations, RPC functions, joins, views
- `reference/realtime-storage.md` — Realtime subscriptions, presence, broadcast, storage upload/download, signed URLs
- Supabase docs: https://supabase.com/docs
- `@supabase/ssr` docs: https://supabase.com/docs/guides/auth/server-side/nextjs

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [iwritec0de](https://github.com/iwritec0de)
- **Source:** [iwritec0de/app-dev](https://github.com/iwritec0de/app-dev)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-iwritec0de-app-dev-supabase
- Seller: https://agentstack.voostack.com/s/iwritec0de
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
