Clerk replaces Supabase Auth across the full stack; Supabase takes over storage

zgbrenner replaced Gary's Supabase Auth with Clerk across both the frontend and backend, and consolidated the data layer on Supabase so the fork can run without any Cloudflare dependency. The migration spans six commits and rewrites auth middleware, session verification, identity lookup, account deletion, and the object storage configuration.

infrastructuresecurity

The frontend half landed in aa9602ce. Custom login/page.tsx and signup/page.tsx (about 285 and 131 lines respectively) were deleted and replaced with Clerk's catch-all login/[[...rest]] and signup/[[...rest]] routes. AppSidebar was rewritten for Clerk sessions, and mikeApi.ts was updated to pass Clerk session tokens to the backend. The .env.local template swaps two Supabase variables for six Clerk ones.

The backend half landed in a7ea67d0. The requireAuth middleware in backend/src/middleware/auth.ts now verifies Clerk session JWTs via @clerk/backend (version 3.4.11, see bun.lock), with a new backend/src/lib/clerk.ts holding the Clerk client. The resolved Clerk user id flows to res.locals.userId, and downstream ownership checks see the same id the frontend uses - the commit notes this as the key payoff, since existing row.user_id === user.id comparisons stay correct. Email resolution moved from Supabase's auth admin API to a Clerk API lookup with a short-lived cache; a missing email is non-fatal and yields no shared items rather than an error.

The schema changes follow from the identity switch. Clerk user ids are not UUIDs, so columns previously referencing auth.users were relaxed to plain text. The Supabase Auth trigger that auto-created profiles on sign-up was dropped; the backend's lazy profile creation handles that instead. Account deletion now calls the Clerk API to remove the user alongside the database cleanup.

Storage also moved in the same pass. The R2_* environment variables were replaced with generic S3_* variables, and Supabase Storage (which exposes an S3-compatible endpoint at https://<project-ref>.supabase.co/storage/v1/s3) becomes the recommended bucket. The existing AWS SDK client code works unchanged - only the env var names changed. A new docs/SUPABASE_SETUP.md covers the storage configuration steps.

d6f10f71 added docs/SETUP_PROGRESS.md tracking the migration state. At the time it merged, Clerk auth was working end to end and Vercel was deployed, but the Supabase database and backend deploy were still pending. That file is marked as a scratchpad to delete once setup is complete. Verify whether it's still present in the version you're evaluating; if it is, the deployment may not have been fully tested.

So what Worth a careful look if you're already considering Clerk for identity management in a Next.js + Express stack, or if you want to drop a Cloudflare dependency. The backend Clerk verification pattern in `backend/src/lib/clerk.ts` and `backend/src/middleware/auth.ts` is the reusable piece. The S3-generic storage config is independently useful. The migration is a deep auth substrate swap rather than a cherry-pickable patch, so plan for a complete review of the token verification and email resolution paths rather than a straight copy.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from zgbrenner/gary, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
5c75082a Merge pull request #6 from foolish-bandit/claude/setup-vercel-supabase-CTH7D Zack Brenner 2026-05-19 ↗ GitHub
Replace Supabase auth with Clerk
dd47abae Merge pull request #7 from foolish-bandit/claude/backend-clerk-supabase Zack Brenner 2026-05-19 ↗ GitHub
Backend Clerk verification + Supabase data layer
7e0e3c56 Merge pull request #8 from foolish-bandit/claude/setup-progress-notes Zack Brenner 2026-05-19 ↗ GitHub
aa9602ce feat: replace Supabase auth with Clerk Claude 2026-05-20 ↗ GitHub
commit body
Swap Gary's built-in Supabase login/signup flow for Clerk so the app can
run as a protected one-person web app on Vercel.

- Add @clerk/nextjs; wrap the root layout in ClerkProvider
- Add Clerk middleware (proxy.ts) that protects every route except
  /login and /signup
- Render Clerk SignIn/SignUp at the existing /login and /signup URLs
- Back the useAuth() compatibility hook with Clerk instead of Supabase
- Replace the sidebar account dropdown with Clerk UserButton
- Send the Clerk session token on backend requests via a shared helper
- Remove the Supabase client, JWT helper, and @supabase/* frontend deps
- Document Clerk env vars and setup in the env examples and docs

The separate Express backend still verifies Supabase JWTs; swapping it to
verify Clerk tokens is a documented follow-up.

https://claude.ai/code/session_018GMAE164ehpBTxzBdsof9r
a7ea67d0 feat: verify Clerk tokens in backend, use Supabase for storage Claude 2026-05-20 ↗ GitHub
commit body
Complete the Clerk migration on the backend side and consolidate the data
layer onto Supabase so Gary can run without Cloudflare.

- Backend auth: requireAuth verifies Clerk session JWTs via @clerk/backend
  instead of Supabase tokens; Clerk user id flows to res.locals.userId
- Resolve user emails through the Clerk API (cached); the sharing/"people"
  endpoints now look users up via Clerk, not Supabase Auth
- Schema: user_profiles and user_api_keys store the Clerk user id as text
  and no longer depend on auth.users; drop the Supabase Auth signup trigger
- Account deletion removes the Clerk user plus the profile/api-key rows
- Storage: switch the S3 client config from R2-specific env vars to generic
  S3_* vars (with a configurable region) so Supabase Storage works
- Remove the dead frontend storage helper and the unused Supabase JWT helper
- Docs: add docs/SUPABASE_SETUP.md and update env examples / deployment docs

https://claude.ai/code/session_018GMAE164ehpBTxzBdsof9r
d6f10f71 docs: add setup progress tracker Claude 2026-05-20 ↗ GitHub
commit body
Records that Clerk auth (frontend + backend) is done and the remaining
Supabase project, storage, and backend-deploy steps are still pending, so
the setup can be resumed without re-deriving where it stands.

https://claude.ai/code/session_018GMAE164ehpBTxzBdsof9r

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-537.md from inside the repo you want the changes in.

⬇ Download capture-thread-537.md