v0 + Already CH: a clean handoff
v0 is the best frontend generator going. The catch is that v0 only ships frontend — there's no backend, no auth, no billing, no compliance scaffold. That's where Already CH picks up.
Both projects use Next.js 15 App Router, shadcn/ui, and Tailwind CSS v4 — the same tokens and primitives. Components copied from v0 work in Already CH without modification.
What carries over without changes
- All shadcn/ui components. Copy v0 output into
components/— done. - Tailwind config. Already CH ships the same default tokens v0 generates against; if you customised, replace Already CH's
tailwind.config.ts. - Page structure. Move v0 pages into the right route group:
(public)for marketing,(app)for authenticated,(billing)for paid features.
What needs migration work
- Data fetching. v0 often generates mock/static data. Replace with Drizzle queries scoped via
withOrgScope(). - Hosting. v0 nudges you toward Vercel. Already CH ships an Exoscale + Coolify deployment recipe — Swiss-resident, Docker-based, runs anywhere.
- Billing. v0 doesn't ship billing. Already CH wires Payrexx for CHF + TWINT + PostFinance with idempotent webhooks and 8.1% VAT.
- Compliance. v0 has no nFADP register. Already CH ships one at
/admin/data-register.
Stack mapping
v0 default → Already CH (Swiss-sovereign)
Next.js 15 + shadcn/ui → Next.js 15 + shadcn/ui (unchanged)
Vercel hosting → Exoscale + Coolify (Docker output:standalone)
No backend → Supabase on Exoscale + Drizzle ORM
No auth → Supabase Auth (MFA, passkeys, org-mandated MFA)
No billing → Payrexx (CHF, TWINT, PostFinance)
No analytics → Matomo (self-hosted, cookie-free)
No compliance UI → /admin/data-register (nFADP Art. 12)
Step-by-step migration
Open your v0 project and copy components/ into Already CH's components/. Tokens and variants paste across without modification — both projects use the same shadcn/ui defaults.
v0: app/dashboard/page.tsx
Already CH: app/(app)/dashboard/page.tsx
v0: app/landing/page.tsx
Already CH: app/(public)/page.tsx
For each v0 page that renders mock data, add a Drizzle schema in db/schema/, then fetch in the Server Component body with withOrgScope().
Wrap any page that needs login in (app)/. The layout's await requireOrg() redirects unauthenticated users to /login.
Create plans in Payrexx with unique CHF amounts. Wire the webhook to /api/webhooks/payrexx. Wrap any paid route with await requirePlan('pro').
Use the included infra/coolify/ service seed JSON. One click in Coolify, your app is running on Exoscale in Geneva or Zurich.
Common questions
Can I still deploy to Vercel?
Technically yes — Already CH's output: standalone Docker image runs anywhere. But if data residency matters, the whole point is to leave Vercel. The Exoscale recipe is the default for a reason.
What about v0's AI assistance?
Use v0 to design new pages, then paste the output into Already CH. The included CLAUDE.md and Cursor rules make Claude Code productive on the rest of the stack.