This is a repo where I can try out new technologies, and eventually write blog posts.
First, install the dependencies:
pnpm install
Skip VS Code dev‑containers? No problem—these steps spin up Supabase locally with nothing more than Docker and the Supabase CLI.
Requirement | Why |
---|---|
Docker Desktop (‑‑ or any Docker runtime) | Supabase uses a small Docker compose stack |
Supabase CLI ≥ 1.179 | Local development & toolbelt https://supabase.com/docs/guides/cli |
Install the CLI with Homebrew:
brew install supabase/tap/supabase
# from apps/server/supabase
supabase start # ‑w to follow logs
The CLI spins up:
Service | Port | Notes |
---|---|---|
Postgres | 54322 | direct DB connection |
REST / GraphQL | 54321 | PostgREST endpoint, GoTrue Auth & GraphQL |
Studio (UI) | 54323 | http://localhost:54323 |
The terminal output also prints anon and service‑role keys for this local project.
Create or update these files so both backend and frontend know how to reach Supabase:
Path | Purpose |
---|---|
apps/server/.env.local |
Used by server-side code and migrations (Hono) |
apps/web/.env.local |
Exposed to the Next.js browser bundle (Next.js) |
apps/server/.env.local
DATABASE_URL=postgres://postgres:postgres@localhost:54322/postgres
DIRECT_URL=postgres://postgres:postgres@localhost:54322/postgres
# Allow browser origin for Supabase REST and your API server
CORS_ORIGIN=http://localhost:3001
apps/web/.env.local (frontend)
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
# paste the ANON_KEY shown by `supabase status -o env`
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
NEXT_PUBLIC_SITE_URL=http://localhost:3001
NEXT_PUBLIC_SERVER_URL=http://localhost:3000
SENTRY_ENV=local
Where to find the keys? Run
supabase status -o env
and copy the values forAPI_URL
andANON_KEY
. If you changesupabase/config.toml
(e.g. Authsite_url
/additional_redirect_urls
), runsupabase stop && supabase start
to apply.
pnpm db:push # runs Drizzle migrations against the local Supabase DB
(Need the visual UI? pnpm db:studio
opens Supabase Studio on http://localhost:54323.)
supabase stop # shut down Docker containers
You now have Supabase + Postgres running locally and seeded with the project schema—time to boot the apps.
pnpm dev # runs web @ :3001 and API @ :3000 concurrently
- Web: http://localhost:3001
- API: http://localhost:3000
If you prefer a standalone Postgres instance instead of Supabase, follow these steps instead:
- Provision a PostgreSQL database.
- Update
apps/server/.env
with the connection string. - Run
pnpm db:push
.
Create apps/web/.env.local
:
PAYLOAD_SECRET=secret
POSTGRES_DATABASE_URI=postgres://postgres:postgres@localhost:54322/postgres
- Create a migration
pnpm payload migrate:create your-migration-name
- Create a new empty migration
pnpm payload migrate:create your-migration-name --skip-empty --force-accept-warning
- See pending/applied migrations
pnpm payload migrate:status
- Apply all pending migrations (runs seed migrations too)
pnpm payload migrate
- Re-run from scratch
pnpm payload migrate:fresh # or: pnpm payload migrate:reset && pnpm payload migrate
Enable the hook in Supabase
- Cloud: Authentication → Hooks → Custom access token → set to
pg-functions://postgres/public/custom_access_token_hook
- Local:
supabase/config.toml
(already enabled)
- Create
pnpm --filter web payload migrate:create your-migration-name --skip-empty --force-accept-warning
- Status
pnpm --filter web payload migrate:status
- Migrate
pnpm --filter web payload migrate
- Stop any running dev server before migrating.
- Don’t mix “push mode” and migrations at the same time.
portfolio/
├── apps/
│ ├── web/ # Frontend application (Next.js)
│ └── server/ # Backend API (Hono, TRPC)
└── supabase/ # Supabase config & migrations (generated by CLI)
Script | What it does |
---|---|
pnpm dev |
Start all applications (web + server) in dev mode |
pnpm build |
Build all applications |
pnpm dev:web |
Start only the web application |
pnpm dev:server |
Start only the server |
pnpm check-types |
Type‑check across all apps |
pnpm db:push |
Push Drizzle migrations to the configured database |
pnpm db:studio |
Open Supabase Studio UI |
pnpm check |
Run Biome formatting & linting |
Happy hacking! 🚀