spinny:~/writing $ less create-demo-claude-code-vibecoding.md
12**Vibecoding** er et nyt softwareudviklingsparadigme, hvor programmøren guider en AI-agent gennem instruktioner på naturligt sprog og lader den kunstige intelligens skrive den faktiske kode. Udtrykket blev opfundet af Andrej Karpathy (medstifter af OpenAI og tidligere Director of AI hos Tesla) i et berømt tweet fra februar 2025: _"There's a new kind of coding I call vibecoding, where you fully give in to the vibes, embrace the exponentials, and forget that the code even exists."_34I denne artikel ser vi, hvordan man bygger en komplet, fungerende demo ved hjælp af **Claude Code** som AI-agent, **Supabase** som backend (database, autentificering, API) og **Vercel** til deployment - alt sammen udelukkende ved hjælp af de **gratis niveauer** af disse tjenester.56## 1. Hvad er vibecoding, og hvorfor er det revolutionerende78Vibecoding repræsenterer et fundamentalt paradigmeskift i softwareudvikling. I stedet for at skrive kode linje for linje:9101. **Beskriver** udvikleren, hvad de ønsker, på naturligt sprog.112. **AI-agenten** genererer den komplette kode.123. **Udvikleren** gennemgår, tester og itererer.1314### Hvorfor det virker1516- **Hastighed**: et projekt, der ville tage dage, kan bygges på timer.17- **Tilgængelighed**: selv ikke-ekspert udviklere kan bygge fungerende produkter.18- **Hurtig iteration**: du kan teste idéer og pivotere meget hurtigere.19- **Produktfokus**: du koncentrerer dig om _hvad_ i stedet for _hvordan_.2021```mermaid22flowchart LR23 A[Idé] --> B[Prompt på naturligt sprog]24 B --> C[Claude Code genererer kode]25 C --> D[Gennemgå og test]26 D --> E[Iteration]27 E --> B28 D --> F[Deploy til Vercel]29```3031### Hvornår skal man bruge vibecoding3233Vibecoding er perfekt til:3435- **Demoer og MVPer**: hurtigt at bygge en prototype for at validere en idé.36- **Hackathons**: at skabe et fungerende produkt på blot et par timer.37- **Sideprojekter**: at udforske nye teknologier uden at investere uger.38- **Proof of Concept**: at demonstrere teknisk gennemførlighed for interessenter eller investorer.3940> **Advarsel:** Vibecoding er fremragende til demoer og prototyper. For produktionsklare applikationer med høje sikkerheds- og skalerbarhedskrav er en grundig gennemgang af den genererede kode stadig essentiel.4142## 2. Tech-stakken: Claude Code + Supabase + Vercel4344### Claude Code4546Claude Code er Anthropics AI-kodningsagent. Den arbejder direkte i din terminal og kan:4748- Læse og forstå hele kodebasen.49- Oprette, ændre og slette filer.50- Udføre terminalkommandoer.51- Interagere med APIer og eksterne tjenester.52- Håndtere versionering med Git.53- Autonomt iterere på fejl og bugs.5455```bash56# Installer Claude Code57npm install -g @anthropic-ai/claude-code5859# Start i en projektmappe60cd my-project61claude62```6364### Supabase (Gratis niveau)6566Supabase er et open source Firebase-alternativ, der tilbyder:6768- **PostgreSQL Database**: en komplet relationel database.69- **Autentificering**: login med e-mail, Google, GitHub osv.70- **REST og Realtime APIer**: automatisk genereret fra dit skema.71- **Storage**: til filer og billeder.72- **Edge Functions**: serverless funktioner.7374Det gratis niveau inkluderer:7576| Ressource | Gratis grænse |77|----------|-----------|78| Database | 500 MB |79| Storage | 1 GB |80| Båndbredde | 5 GB |81| Edge Function-kald | 500K/måned |82| Autentificerede brugere | Ubegrænset |83| Projekter | 2 aktive projekter |8485### Vercel (Gratis niveau)8687Vercel er den perfekte deployment-platform for Next.js-applikationer:8889- **Automatisk deployment** fra GitHub.90- **Preview deployments** for hver branch og PR.91- **Global CDN** for optimal ydeevne.92- **Serverless Functions** inkluderet.93- **Grundlæggende analytics** gratis.9495Det gratis niveau inkluderer:9697| Ressource | Gratis grænse |98|----------|-----------|99| Båndbredde | 100 GB/måned |100| Serverless Function-udførelse | 100 GB-timer/måned |101| Builds | 6.000 minutter/måned |102| Projekter | Ubegrænset |103| Deployments | Ubegrænset |104105## 3. Indledende opsætning: Forberedelse af miljøet106107### Forudsætninger108109Før du begynder, skal du sikre dig, at du har:110111- **Node.js 18+** installeret.112- **Git** konfigureret.113- En **GitHub**-konto.114- En **Supabase**-konto (gratis på [supabase.com](https://supabase.com)).115- En **Vercel**-konto (gratis på [vercel.com](https://vercel.com)).116- **Claude Code** installeret (`npm install -g @anthropic-ai/claude-code`).117118### Trin 1: Opret projektet119120Åbn terminalen og start Claude Code:121122```bash123mkdir my-demo-app && cd my-demo-app124claude125```126127Nu kan du begynde at give Claude Code instruktioner på naturligt sprog:128129```130Du: Opret et Next.js 15-projekt med App Router, TypeScript, Tailwind CSS131og shadcn/ui. Initialiser også et Git-repository.132```133134Claude Code vil automatisk udføre:135136```bash137npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir138npx shadcn@latest init139git init && git add . && git commit -m "Initial commit"140```141142### Trin 2: Konfigurer Supabase1431441. Gå til [supabase.com](https://supabase.com) og opret et nyt projekt.1452. Notér **Project URL** og **anon key** fra Settings > API.1463. Gå tilbage til terminalen med Claude Code:147148```149Du: Tilføj Supabase til projektet. Opret en .env.local-fil med variablerne150NEXT_PUBLIC_SUPABASE_URL og NEXT_PUBLIC_SUPABASE_ANON_KEY. Konfigurer151Supabase-klienten med SSR-understøttelse til Next.js App Router.152```153154Claude Code vil oprette den komplette konfiguration:155156```typescript157// src/lib/supabase/client.ts158import { createBrowserClient } from '@supabase/ssr';159160export function createClient() {161 return createBrowserClient(162 process.env.NEXT_PUBLIC_SUPABASE_URL!,163 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!164 );165}166```167168```typescript169// src/lib/supabase/server.ts170import { createServerClient } from '@supabase/ssr';171import { cookies } from 'next/headers';172173export async function createClient() {174 const cookieStore = await cookies();175176 return createServerClient(177 process.env.NEXT_PUBLIC_SUPABASE_URL!,178 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,179 {180 cookies: {181 getAll() {182 return cookieStore.getAll();183 },184 setAll(cookiesToSet) {185 cookiesToSet.forEach(({ name, value, options }) =>186 cookieStore.set(name, value, options)187 );188 },189 },190 }191 );192}193```194195## 4. Opbygning af demoen: En opgavestyringsapp196197Lad os bygge en konkret demo: en **opgavestyringsapp** med autentificering, fuld CRUD og et moderne interface.198199### Definer databaseskemaet200201Giv Claude Code instruktioner til at oprette skemaet:202203```204Du: Opret en SQL-migration til Supabase med følgende tabeller:2052061. profiles: id (uuid, FK til auth.users), username (text), avatar_url (text),207 created_at2082. projects: id (uuid), name (text), description (text), owner_id (uuid, FK209 til profiles), created_at2103. tasks: id (uuid), title (text), description (text), status (enum:211 todo/in_progress/done), priority (enum: low/medium/high), project_id (uuid,212 FK til projects), assigned_to (uuid, FK til profiles), due_date (timestamp),213 created_at, updated_at214215Aktiver Row Level Security på alle tabeller og opret passende policies.216```217218Claude Code vil generere en komplet migration:219220```sql221-- Create enum types222CREATE TYPE task_status AS ENUM ('todo', 'in_progress', 'done');223CREATE TYPE task_priority AS ENUM ('low', 'medium', 'high');224225-- Profiles table226CREATE TABLE profiles (227 id UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY,228 username TEXT UNIQUE,229 avatar_url TEXT,230 created_at TIMESTAMPTZ DEFAULT NOW()231);232233-- Projects table234CREATE TABLE projects (235 id UUID DEFAULT gen_random_uuid() PRIMARY KEY,236 name TEXT NOT NULL,237 description TEXT,238 owner_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,239 created_at TIMESTAMPTZ DEFAULT NOW()240);241242-- Tasks table243CREATE TABLE tasks (244 id UUID DEFAULT gen_random_uuid() PRIMARY KEY,245 title TEXT NOT NULL,246 description TEXT,247 status task_status DEFAULT 'todo',248 priority task_priority DEFAULT 'medium',249 project_id UUID REFERENCES projects(id) ON DELETE CASCADE NOT NULL,250 assigned_to UUID REFERENCES profiles(id),251 due_date TIMESTAMPTZ,252 created_at TIMESTAMPTZ DEFAULT NOW(),253 updated_at TIMESTAMPTZ DEFAULT NOW()254);255256-- Enable RLS257ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;258ALTER TABLE projects ENABLE ROW LEVEL SECURITY;259ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;260261-- Profiles policies262CREATE POLICY "Users can view own profile"263 ON profiles FOR SELECT USING (auth.uid() = id);264CREATE POLICY "Users can update own profile"265 ON profiles FOR UPDATE USING (auth.uid() = id);266267-- Projects policies268CREATE POLICY "Users can view own projects"269 ON projects FOR SELECT USING (auth.uid() = owner_id);270CREATE POLICY "Users can create projects"271 ON projects FOR INSERT WITH CHECK (auth.uid() = owner_id);272CREATE POLICY "Users can update own projects"273 ON projects FOR UPDATE USING (auth.uid() = owner_id);274CREATE POLICY "Users can delete own projects"275 ON projects FOR DELETE USING (auth.uid() = owner_id);276277-- Tasks policies278CREATE POLICY "Users can view tasks in their projects"279 ON tasks FOR SELECT USING (280 project_id IN (SELECT id FROM projects WHERE owner_id = auth.uid())281 );282CREATE POLICY "Users can create tasks in their projects"283 ON tasks FOR INSERT WITH CHECK (284 project_id IN (SELECT id FROM projects WHERE owner_id = auth.uid())285 );286CREATE POLICY "Users can update tasks in their projects"287 ON tasks FOR UPDATE USING (288 project_id IN (SELECT id FROM projects WHERE owner_id = auth.uid())289 );290CREATE POLICY "Users can delete tasks in their projects"291 ON tasks FOR DELETE USING (292 project_id IN (SELECT id FROM projects WHERE owner_id = auth.uid())293 );294```295296Du kan køre denne migration direkte fra Supabase-dashboardet (SQL Editor) eller via CLI.297298### Generer TypeScript-typer299300```301Du: Generer TypeScript-typer fra Supabase-databasen og gem dem i src/types/database.ts302```303304```bash305npx supabase gen types typescript --project-id YOUR_PROJECT_ID > src/types/database.ts306```307308### Byg brugergrænsefladen309310Nu kommer den mest kraftfulde del af vibecoding. Giv Claude Code instruktioner på højt niveau:311312```313Du: Opret en dashboard-side til opgavestyringsappen med:3143151. Sidebar med navigation mellem projekter3162. Kanban-visning med 3 kolonner (Todo, In Progress, Done) med drag & drop3173. Modal til at oprette/redigere opgaver3184. Header med brugeravatar og logout3195. Moderne design med shadcn/ui og Tailwind320321Brug data fra Supabase med React Server Components hvor muligt322og Client Components kun hvor interaktivitet er nødvendig.323```324325Claude Code vil bygge hele grænsefladen, komponent for komponent.326327### Tilføj autentificering328329```330Du: Tilføj et komplet autentificeringssystem med:3313321. Login-side med e-mail/adgangskode og GitHub-login3332. Registreringsside3343. Middleware til at beskytte autentificerede ruter3354. Automatisk omdirigering for uautentificerede brugere3365. Automatisk profiloprettelse efter registrering337```338339Claude Code vil konfigurere Next.js middleware og auth-sider:340341```typescript342// src/middleware.ts343import { createServerClient } from '@supabase/ssr';344import { NextResponse, type NextRequest } from 'next/server';345346export async function middleware(request: NextRequest) {347 let supabaseResponse = NextResponse.next({ request });348349 const supabase = createServerClient(350 process.env.NEXT_PUBLIC_SUPABASE_URL!,351 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,352 {353 cookies: {354 getAll() {355 return request.cookies.getAll();356 },357 setAll(cookiesToSet) {358 cookiesToSet.forEach(({ name, value }) =>359 request.cookies.set(name, value)360 );361 supabaseResponse = NextResponse.next({ request });362 cookiesToSet.forEach(({ name, value, options }) =>363 supabaseResponse.cookies.set(name, value, options)364 );365 },366 },367 }368 );369370 const { data: { user } } = await supabase.auth.getUser();371372 if (!user && !request.nextUrl.pathname.startsWith('/auth')) {373 const url = request.nextUrl.clone();374 url.pathname = '/auth/login';375 return NextResponse.redirect(url);376 }377378 return supabaseResponse;379}380381export const config = {382 matcher: ['/((?!_next/static|_next/image|favicon.ico|auth).*)'],383};384```385386## 5. Avancerede vibecoding-mønstre387388### Iterativ prompting389390Hemmeligheden bag effektiv vibecoding er **iteration**. Forsøg ikke at beskrive alt i en enkelt prompt. Fortsæt trinvist:391392```393Trin 1: "Opret det grundlæggende layout med header og sidebar"394Trin 2: "Tilføj projektlisten i sidebaren med en knap til at oprette nye"395Trin 3: "Opret Kanban-visningen i hovedområdet"396Trin 4: "Tilføj drag & drop mellem kolonner"397Trin 5: "Implementer modalen til at oprette nye opgaver"398Trin 6: "Tilføj toast-notifikationer for brugerfeedback"399```400401> **Tip:** Jo mere specifik og kontekstualiseret prompten er, desto bedre er resultatet. Claude Code har adgang til hele kodebasen, så den kan integrere nye funktioner sammenhængende.402403### Fejlhåndtering404405Når noget ikke virker (og det vil det), kan du simpelthen sige:406407```408Du: Jeg får denne fejl i konsollen: "TypeError: Cannot read property409'map' of undefined" i TaskList-komponenten. Ret det.410```411412Claude Code vil analysere koden, identificere problemet og rette det.413414### Refaktorering med AI415416```417Du: Dashboard-komponenten er blevet for stor. Opdel den i mindre,418genanvendelige komponenter, mens den samme funktionalitet bevares.419```420421### Test422423```424Du: Tilføj tests med Vitest til utility-funktioner og Playwright-tests til425autentificerings- og opgaveoprettelsesflowet.426```427428## 6. Deploy til Vercel: Fra kode til verden429430### Trin 1: Push til GitHub431432```433Du: Opret en passende .gitignore, commit alt, og push til et nyt434GitHub-repository kaldet "my-demo-app".435```436437```bash438git add .439git commit -m "feat: complete task management demo"440gh repo create my-demo-app --public --push --source=.441```442443### Trin 2: Forbind Vercel4444451. Gå til [vercel.com](https://vercel.com) og klik "Add New Project."4462. Importér det GitHub-repository, du lige har oprettet.4473. Tilføj miljøvariabler:448 - `NEXT_PUBLIC_SUPABASE_URL`449 - `NEXT_PUBLIC_SUPABASE_ANON_KEY`4504. Klik "Deploy."451452```mermaid453flowchart LR454 A[GitHub Push] --> B[Vercel Build]455 B --> C[Automatisk Deploy]456 C --> D[Offentlig URL]457 D --> E[Global CDN]458```459460### Trin 3: Konfigurer et brugerdefineret domæne (valgfrit)461462Vercel giver en gratis URL som `my-demo-app.vercel.app`. For et brugerdefineret domæne:463464```465Du: Tilføj konfigurationen for et brugerdefineret domæne i vercel.json466```467468### Preview Deployments469470Hver gang du åbner en Pull Request på GitHub, vil Vercel automatisk oprette et **preview deployment** med en unik URL. Perfekt til at vise ændringer før merge.471472## 7. Optimeringer til din demo473474### Ydeevne475476```477Du: Optimer appens ydeevne:4781. Tilføj indlæsningstilstande med Suspense og skeletons4792. Implementer caching med Next.js unstable_cache4803. Optimer billeder med next/image4814. Tilføj SEO-metadata til hver side482```483484### Realtime med Supabase485486En funktion, der altid imponerer i demoer, er **realtime**:487488```489Du: Tilføj realtids-synkronisering for opgaver ved hjælp af Supabase Realtime.490Når en bruger opdaterer en opgave, skal alle andre brugere se ændringen491i realtid uden at genindlæse.492```493494```typescript495'use client';496497import { useEffect, useState } from 'react';498import { createClient } from '@/lib/supabase/client';499import type { Task } from '@/types/database';500501export function useRealtimeTasks(projectId: string) {502 const [tasks, setTasks] = useState<Task[]>([]);503 const supabase = createClient();504505 useEffect(() => {506 const channel = supabase507 .channel('tasks-changes')508 .on(509 'postgres_changes',510 {511 event: '*',512 schema: 'public',513 table: 'tasks',514 filter: `project_id=eq.${projectId}`,515 },516 (payload) => {517 if (payload.eventType === 'INSERT') {518 setTasks((prev) => [...prev, payload.new as Task]);519 } else if (payload.eventType === 'UPDATE') {520 setTasks((prev) =>521 prev.map((t) =>522 t.id === payload.new.id ? (payload.new as Task) : t523 )524 );525 } else if (payload.eventType === 'DELETE') {526 setTasks((prev) =>527 prev.filter((t) => t.id !== payload.old.id)528 );529 }530 }531 )532 .subscribe();533534 return () => {535 supabase.removeChannel(channel);536 };537 }, [projectId, supabase]);538539 return tasks;540}541```542543### Mørk tilstand544545```546Du: Tilføj understøttelse af mørk tilstand med en skifteknap i headeren.547Brug Tailwind dark-klasser og gem præferencen i localStorage.548```549550## 8. Bedste praksis for effektiv vibecoding551552### 1. Vær specifik i dine prompts553554```555Nej: "Lav en pæn side"556Ja: "Opret en landingsside med en hero-sektion med en lilla-blå gradient,557 en funktions-sektion med 3 kort med ikoner og en orange CTA-knap"558```559560### 2. Giv kontekst561562```563Nej: "Tilføj autentificering"564Ja: "Tilføj autentificering med Supabase Auth. Projektet bruger Next.js 15 App565 Router med TypeScript. Jeg vil have e-mail/adgangskode-login og OAuth med GitHub.566 Brug SSR-mønsteret med @supabase/ssr"567```568569### 3. Iterer i små trin570571Forsøg ikke at bygge alt i en enkelt prompt. Fortsæt trinvist:5725731. Grundlæggende layout5742. Én funktion ad gangen5753. Styling og finpudsning5764. Fejlhåndtering5775. Test578579### 4. Gennemgå den genererede kode580581Vibecoding betyder ikke, at man ikke læser koden. Gennemgå altid:582583- **Sikkerhed**: RLS-politikker, inputvalidering, datasanering.584- **Ydeevne**: N+1-forespørgsler, unødvendigt klientside-komponenter.585- **Bedste praksis**: projektstruktur, navngivningskonventioner.586587### 5. Brug Git strategisk588589```590Du: Commit ændringerne med en beskrivende besked efter hver fuldført funktion.591```592593Dette giver dig mulighed for at rulle tilbage, hvis noget går galt.594595## 9. Omkostninger: Er det virkelig alt gratis?596597Her er en omkostningsoversigt for hver tjeneste:598599| Tjeneste | Gratis plan | Hvornår du betaler |600|---------|-----------|-------------|601| **Claude Code** | Kræver et Anthropic-abonnement (fra $20/måned) eller API-nøgle | Med det samme, men værdien er enorm |602| **Supabase** | Generøst gratis niveau (2 projekter, 500MB DB) | Ud over gratis niveauets grænser |603| **Vercel** | Gratis niveau til personlige projekter | For teams eller kommerciel brug |604| **GitHub** | Gratis til offentlige og private repos | Enterprise-funktioner |605606> **Bemærk:** Claude Code kræver et abonnement eller API-kreditter, men afkastet i form af udviklingshastighed er ekstraordinært. For en demo eller MVP er de samlede omkostninger i området $20.607608### Gratis AI-alternativer609610Hvis du vil holde omkostningerne på absolut nul, kan du bruge:611612- **Cursor** (gratis niveau med begrænsninger).613- **GitHub Copilot** (gratis for studerende og open source).614- **Codeium/Windsurf** (generøst gratis niveau).615616## 10. Fra demo til produkt: Næste trin617618Når din demo er live, er her hvordan du fortsætter:619620```mermaid621flowchart TD622 A[Live Demo] --> B{Brugerfeedback}623 B --> C[Produktiteration]624 C --> D[Product-Market Fit]625 D --> E[Skalering]626 E --> F[Supabase Pro Plan]627 E --> G[Vercel Pro Plan]628 E --> H[Brugerdefineret domæne]629```6306311. **Indsaml feedback**: del demoen med potentielle brugere og indsaml meninger.6322. **Iterer hurtigt**: brug vibecoding til at implementere de ønskede ændringer.6333. **Overvåg metrics**: Vercel Analytics og Supabase Dashboard giver dig essentielle data.6344. **Skalér når nødvendigt**: opgrader til betalte planer først, når du har valideret efterspørgslen.635636637## Konklusion638639Vibecoding med Claude Code, Supabase og Vercel repræsenterer en kraftfuld kombination til at bygge demoer og MVPer på rekordtid. Det, der plejede at tage uger af udvikling, kan nu opnås på blot et par timer med et overraskende højt kvalitetsniveau.640641Nøglen er at nærme sig vibecoding med den rette tankegang: det handler ikke om "ikke at vide, hvordan man koder", men om at **forstærke dine evner** med AI-værktøjer. Jo mere du ved om de underliggende teknologier (React, SQL, autentificering, deployment), jo mere effektiv vil du være til at guide AI-agenten mod det ønskede resultat.642643Fremtiden for softwareudvikling er her, og prisen for at komme i gang har aldrig været lavere. Opret din demo, validér den med rigtige brugere, og byg det næste store produkt.644645> **Tjekliste til din første demo:**646>647> - [x] Claude Code installeret og konfigureret648> - [x] Supabase-projekt oprettet med databaseskema649> - [x] Next.js-projekt initialiseret med shadcn/ui650> - [x] Autentificering konfigureret651> - [x] Fuld CRUD implementeret652> - [x] Moderne og responsiv UI653> - [x] Deployed til Vercel654> - [x] Delbar URL klar til feedback655
:Sådan bygger du en demo med Claude Code: Vibecoding med Supabase og Vercellines 1-655 (END) — press q to close