Quick Start
Go from empty .env to a working directory in 15 minutes.
This is the fastest path to a working site. By the end, you'll have Supabase connected, the database set up, and your brand on the page.
Make sure Installation is done — you should be able to run pnpm dev and see the site (even if features don't fully work).
1. Create a Supabase project (3 min)
Supabase gives you a database, user auth, and file storage in one dashboard.
- Go to supabase.com → New Project
- Pick a name, set a database password (save it in a password manager), choose a region close to you
- Wait ~2 minutes for the project to boot

2. Copy your Supabase keys (1 min)
Once your project is ready:
- Open Settings → API in the left sidebar
- You'll see three values you'll need:
- Project URL — something like
https://abcdefgh.supabase.co - anon / public key — safe to use in the browser
- service_role / secret key — server-only, bypasses all security
- Project URL — something like

The service_role key bypasses all database security. Keep it in .env.local only. Never paste it into frontend code or commit it to Git.
3. Run the database schema (2 min)
The project ships with a single SQL file that creates every table, index, and permission rule. You run it once in Supabase.
- In Supabase, open SQL Editor (left sidebar) → New query
- Open
supabase/schema.sqlfrom the project, copy everything - Paste into the Supabase SQL Editor and click Run

The script is idempotent — safe to run multiple times.
4. Fill in your .env.local (2 min)
Open .env.local and paste the Supabase values:
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_SUPABASE_URL=https://abcdefgh.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...your-anon-key
SUPABASE_SERVICE_ROLE_KEY=eyJ...your-service-role-key
CRON_SECRET=any-long-random-stringCRON_SECRET can be any random string — just make it hard to guess. You can generate one with:
openssl rand -hex 32You can leave the Stripe and Resend keys empty for now. Pages that use them will show errors, but the rest of the site works.
5. Restart the dev server (30 sec)
Stop the dev server (Ctrl+C) and start it again so it picks up the new env vars:
pnpm dev6. Your directory is alive
Open http://localhost:3000.
Try it:
- Click Sign in → create an account (uses Supabase Auth)
- Go to
/submit→ submit a test project - Log in as admin (see below) →
/adminto approve it
Make yourself admin
- In Supabase, go to Table Editor →
users - Find your row, set
is_admintotrueandroletoadmin - Reload — you now have access to
/admin
The schema has two admin mechanisms: is_admin (boolean) and role (text). Keep them in sync — set both to admin when granting access.
7. Brand it in 2 minutes
Open config/site.config.ts and change three fields:
export const siteConfig = {
name: 'My Directory',
tagline: 'Curated tools for X',
url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
// ...
contact: {
email: 'hello@mydirectory.com',
supportEmail: 'support@mydirectory.com',
privacyEmail: 'privacy@mydirectory.com',
},
};Save — the dev server hot-reloads, and the name / tagline update everywhere.
Or let an AI do it for you:
Open config/site.config.ts and set the following fields:
- name: "{your brand name}"
- tagline: "{one-line pitch, under 60 chars}"
- description: "{longer SEO description, 1-2 sentences}"
- contact.email: "{hello@yourdomain.com}"
- contact.supportEmail: "{support@yourdomain.com}"
- contact.privacyEmail: "{privacy@yourdomain.com}"
- social.twitter: "{@handle or full URL}"
- keywords: [{3-5 relevant SEO keywords}]
- themeColor: "{brand hex color}"
Keep every other field as-is. Match the existing SiteConfig type.
What's next
You now have a working directory. Next decisions:
- Add payments? → Payments (Stripe setup)
- Add email? → Email Config (Resend setup)
- Go live? → Deploy in 5 Minutes
- Customize colors? → Theming