Serie: Vibe Coding auf eigene Faust — Teil 1 von 2
Ausblick auf Teil 2: „Von Localhost zu Live: Wie du deine vibe-gecodete App auf einen Cloud-Webserver bringst"
Alternative Überschriften-Optionen:
- Bau dir dein eigenes Lovable: Ein kostenloses, lokales Vibe-Coding-Setup für den Mac
- Vibe Coding ohne Abo: VSCode + Cline + Ollama + Supabase
Was ist eigentlich Vibe Coding?
Vibe Coding ist eine Art, Software zu bauen, bei der du in normaler Sprache beschreibst, was du willst, und eine KI den Code schreibt — während du steuerst, reviewst und auf das reagierst, was auf dem Bildschirm erscheint. Du bleibst als Produktmensch am Steuer: „füge einen Dark-Mode-Toggle hinzu", „der Löschen-Button soll nach Bestätigung fragen", „sortiere die Liste nach Datum". Die KI kümmert sich um Syntax, Dateistruktur und Boilerplate. Du kümmerst dich um den Vibe: was die App tun soll und wie sie sich anfühlen soll.
Der Begriff nahm Anfang 2025 Fahrt auf (geprägt vom KI-Forscher Andrej Karpathy) und traf einen Nerv, weil er etwas Reales beschreibt: Für eine riesige Klasse von Apps — interne Tools, Prototypen, Side Projects, kleine Produkte — musst du den Großteil des Codes nicht mehr selbst schreiben. Du musst in der Lage sein, das Schreiben von Code zu dirigieren — und zu erkennen, wenn etwas nicht stimmt.
Was ist Lovable?
Lovable ist eine der beliebtesten Vibe-Coding-Plattformen. Du tippst in eine Chatbox, was du willst, und sie baut vor deinen Augen eine funktionierende Web-App — Benutzeroberfläche, Datenbank, Login, Datei-Uploads, das ganze Programm — mit einer Live-Vorschau, die sich aktualisiert, während du schreibst. Unter der Haube generiert Lovable einen ziemlich standardmäßigen modernen Web-Stack: React mit TypeScript, gestylt mit Tailwind CSS und shadcn/ui-Komponenten, dahinter Supabase (eine Postgres-Datenbank mit eingebauter Authentifizierung und Dateispeicher).
Es ist ein großartiges Produkt. Es ist aber auch ein Abo mit nutzungsbasierten Credits, dein Code liegt in deren Cloud, und die KI-Aufrufe gehen an kommerzielle Modelle. Was für Bastler eine naheliegende Frage aufwirft:
Kann man sich dieselbe Erfahrung selbst zusammenbauen — kostenlos, lokal und privat?
Ja. Genau darum geht es in diesem Beitrag.
Das Ziel dieses Beitrags
Am Ende hast du eine komplette Vibe-Coding-Umgebung auf deinem Mac laufen:
| Was Lovable dir gibt | Dein kostenloses lokales Äquivalent |
|---|---|
| Chatbox, die die App baut | Cline (ein KI-Coding-Agent direkt in VSCode) |
| Das KI-Gehirn | Ollama mit einem lokal laufenden Open-Source-Modell |
| Live-Vorschau | Vite Dev-Server in deinem Browser, mit Hot Reload bei jeder Änderung |
| Versteckter Code | VSCode — derselbe Code, nur dass du ihn sehen und anfassen kannst |
| Datenbank, Auth, Storage | Supabase lokal in Containern — exakt dieselbe Technologie, die Lovable in der Cloud nutzt |
| Ein-Klick-Publishing | Kommt in Teil 2 dieser Serie |
Gesamtkosten: 0 €. Dein Code verlässt nie deinen Rechner. Deine Prompts verlassen nie deinen Rechner. Und weil es derselbe Stack ist, den Lovable verwendet, hat alles, was du baust, später einen sauberen Weg zu echtem Cloud-Hosting.
Eine ehrliche Erwartungsjustierung, bevor wir loslegen: Ein lokales Open-Source-Modell auf Consumer-Hardware ist nicht so leistungsfähig wie die Frontier-Modelle, die Lovable mietet. Dein lokaler Agent wird gelegentlich etwas Dummes tun, und dieser Beitrag zeigt dir die Leitplanken, die das beherrschbar halten (sie sind die halbe Miete dieses Artikels — ich bin beim Setup in jede der unten beschriebenen Stolperfallen tatsächlich selbst getappt).
Was du vor dem Start brauchst
- Einen Mac (Apple Silicon empfohlen; 16 GB RAM sind komfortabel, 8 GB funktionieren mit den Tricks im RAM-Abschnitt weiter unten)
- VSCode installiert, mit der Cline-Extension
- Ollama installiert, mit einem heruntergeladenen Coding-Modell —
qwen2.5-coder(7b oder 14b) ist derzeit eine der stärksten Optionen, die auf Consumer-Hardware passen
Das Setup von VSCode + Cline + Ollama ist anderswo gut dokumentiert; dieser Beitrag beginnt dort, wo die meisten Guides aufhören: beim lokalen Testserver und der Datenbank — dem Teil, der aus „einer KI, die Dateien editiert" eine „Lovable-artige Erfahrung mit einer echten laufenden App" macht.
Phase 1: Einmaliges Maschinen-Setup (~20 Minuten)
Vier Kommandozeilen-Tools, einmal installiert, von jedem zukünftigen Projekt genutzt. Öffne das Terminal (in VSCode: Terminal → New Terminal).
1. Homebrew — der Paketmanager des Mac
Prüfe, ob du es schon hast:
brew --versionWenn das eine Version ausgibt, weiter zum nächsten Schritt. Wenn nicht:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Auf Apple Silicon führst du noch die zwei zusätzlichen Befehle aus, die der Installer am Ende ausgibt (sie fügen brew deinem PATH hinzu), und öffnest dann ein neues Terminal.
2. OrbStack — die Container-Runtime
Deine lokale Datenbank läuft in Containern. Das übliche Tool dafür ist Docker Desktop, aber OrbStack ist ein Drop-in-Ersatz, der spürbar weniger RAM und Akku verbraucht — und RAM zählt, denn Ollama frisst davon ohnehin schon eine Menge.
brew install orbstack
open -a OrbStackBestätige die Abfragen; danach lebt es unauffällig in deiner Menüleiste. Verifizieren:
docker --version3. Node.js — betreibt den Dev-Server
brew install node
node -vStolperfalle #1 — gruselig aussehende Installationsmeldungen. Homebrew gibt eventuell „Caveats" aus wie "Single Executable Application is disabled" oder "Temporal support is disabled." Das sieht nach Fehlern aus; es sind aber harmlose Hinweise zu Nischen-Features von Node, die nichts in diesem Stack verwendet. Wenn du das 🍺-Bierglas siehst, war die Installation erfolgreich.
4. Supabase CLI — dein komplettes Backend in einem Tool
brew install supabase
supabase --versionDas ist der Baustein, den die meisten Guides auslassen. Die Supabase CLI betreibt ein komplettes lokales Backend — Postgres-Datenbank, Authentifizierung, Dateispeicher und eine visuelle Admin-Oberfläche — mit einem einzigen Befehl. Es ist dieselbe Open-Source-Software, die hinter Lovables Cloud-Backend steckt. Du installierst oder konfigurierst Postgres nie selbst.
Phase 2: Ein Projekt anlegen (~20 Minuten, einmal pro Projekt)
5. Die App aufsetzen
Wähle einen Ordner, in dem alle deine Projekte leben sollen, und bleibe eisern dabei:
mkdir -p ~/Projects && cd ~/Projects
npm create vite@latest my-first-app -- --template react-ts
cd my-first-app
npm installDer Scaffolder fragt "Which linter to use?" — wähle ESLint. Es ist der langjährig etablierte Standard, und (ein Thema, das dir hier noch öfter begegnen wird) lokale KI-Modelle haben im Training weit mehr ESLint-Projekte gesehen als neuere Alternativen, machen damit also weniger Fehler.
Öffne das Projekt in VSCode mit code . — und falls das Terminal command not found: code meldet, ist das eine einmalige VSCode-Einstellung: drücke Cmd+Shift+P, tippe „shell command", wähle "Shell Command: Install 'code' command in PATH" und öffne dann ein neues Terminal.
Stolperfalle #2 — die Falscher-Ordner-Falle. Das hat mich mehr Zeit gekostet als alles andere im gesamten Setup. Wenn du VSCode öffnest, während dein Terminal in irgendeinem anderen Verzeichnis steht, landen deine Änderungen im falschen Projekt — und spätere Befehle schlagen auf mysteriöse Weise fehl, weil die Dateien, die sie erwarten, nie geändert wurden. Zwei Gewohnheiten verhindern das komplett: Wirf vor jedem Befehl einen Blick auf den Terminal-Prompt oder führe pwd aus — es muss auf deinen Projektnamen enden; und öffne in VSCode über File → Open Folder exakt den Projektordner, nichts darüber.Jetzt verifiziere das Herzstück des Setups — deinen lokalen Testserver:
npm run devÖffne http://localhost:5173 — die Starter-Seite lädt. Dieser Vite-Server lädt den Browser per Hot Reload innerhalb einer Sekunde nach jeder Dateiänderung neu — genau das erzeugt das Lovable-Gefühl von „zuschauen, wie es live gebaut wird". Lass ihn in seinem eigenen Terminal-Tab laufen; öffne für andere Befehle neue Tabs (das +-Icon).
Stolperfalle #3 — Port 5174? Wenn die URL jemals 5174 statt 5173 zeigt, läuft ein zweiter Dev-Server in einem vergessenen Terminal-Tab. Nicht schädlich, aber verwirrend. Schließe die Duplikate; lass genau einen laufen.
6. Tailwind CSS + shadcn/ui — Lovables visuelle Sprache
npm install tailwindcss @tailwindcss/vite(Falls npm wegen fsevents und "install scripts not yet covered by allowScripts" warnt — das ist ein neueres npm-Sicherheitsfeature. fsevents ist ein vertrauenswürdiger macOS-Helfer für Dateiüberwachung; genehmige ihn mit npm approve-scripts fsevents oder mach einfach weiter, es funktioniert so oder so.)
Ersetze den gesamten Inhalt von src/index.css durch eine einzige Zeile:
@import "tailwindcss";Stolperfalle #4 — Einfügen heißt ersetzen, nicht anhängen. Wenn ein Guide sagt „ersetze den Dateiinhalt", dann: alles markieren (Cmd+A), löschen, dann einfügen. Ich habe es geschafft, eine neuevite.config.tsunter die alte zu pasten — das Ergebnis war eine Datei mit doppelten Imports und zwei Default-Exports, sofortiger Totalschaden. Wenn direkt nach einer Änderung etwas Fehler wirft, prüfe, ob du den Inhalt der Datei nicht doppelt drin hast.
Jetzt, bevor du den Installer von shadcn ausführst, erledige das Setup, das er stillschweigend voraussetzt. Das ist der Schritt, an dem mein Setup zum ersten Mal richtig gescheitert ist:
Stolperfalle #5 — shadcn braucht einen „Import Alias", den Vite nicht mitliefert. shadcn/ui schreibt Komponenten, die aus@/components/...importieren — das@ist eine Kurzform für deinensrc-Ordner. Das Vite-Template definiert diese Kurzform nicht, weshalbnpx shadcn initan seinen Preflight-Checks mit "Could not find valid path aliases." scheitert. Der Fix besteht aus drei kleinen Änderungen, einmal pro Projekt:
Installiere den Typ-Helfer:
npm install -D @types/nodeErsetze vite.config.ts durch:
import path from "path"
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: { "@": path.resolve(__dirname, "./src") },
},
})Ersetze tsconfig.json durch:
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}Und füge in tsconfig.app.json diese zwei Zeilen oben im bestehenden "compilerOptions"-Block hinzu:
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] },Jetzt besteht shadcn seine Checks:
npx shadcn@latest init
npx shadcn@latest add button card inputDas Init stellt zwei Fragen, die aktuelle Guides selten erwähnen. "Select a component library?" — wähle Radix UI, auch wenn das Tool Base UI empfiehlt. Radix ist das, worauf shadcn ursprünglich gebaut wurde und was Lovable verwendet — was wiederum bedeutet: Es ist das, was deine lokalen Modelle am besten kennen. "Which preset?" — Nova (Lucide-Icons, der klassische shadcn-Look). Bei allem anderen die Defaults.
7. Dein lokales Backend + die Datenbank starten
supabase init
supabase startDas erste supabase start lädt rund ein Dutzend Container-Images herunter — gib ihm ein paar Minuten.
Stolperfalle #6 — ein Download schlägt zufällig fehl. Eines meiner dreizehn Images (storage-api) ließ sich mit einem kryptischen Registry-Fehler nicht ziehen, während die anderen zwölf durchliefen. An meinem Setup war nichts falsch — Container-Registries haben gelegentlich Schluckauf. Der Fix ist unspektakulär:supabase starteinfach noch einmal ausführen. Es setzt fort und holt nur das nach, was fehlt.
Wenn es fertig ist, zeigt dir supabase status, was du jetzt hast:
| Service | Adresse |
|---|---|
| Deine App (Testserver) | http://localhost:5173 |
| Studio — visuelle Datenbank-Verwaltung | http://127.0.0.1:54323 |
| API (REST/Auth/Storage) | http://127.0.0.1:54321 |
| Postgres, Direktverbindung | Port 54322 |
Öffne Studio im Browser und sieh dich um: Tabellen-Editor, SQL-Konsole, Auth-User, Storage-Buckets. Das ist dein Fenster in die Datenbank für den gesamten Vibe-Coding-Workflow — wenn die KI behauptet, etwas gespeichert zu haben, prüfst du in Studio, ob sie es wirklich getan hat.
(Eventuell siehst du auch "Stopped services: imgproxy, pooler" — das sind optionale Komponenten; das ist normal.)
8. Die App mit der Datenbank verdrahten
npm install @supabase/supabase-jsStolperfalle #7 — die Keys sehen nicht so aus, wie die Tutorials sagen. Die meisten Guides sagen dir, du sollst einen „anon key" kopieren, der wieeyJhbGci...aussieht. Neuere Supabase-Versionen haben dieses Format ersetzt:supabase statusgibt jetzt einen Publishable Key (sb_publishable_...) und einen Secret Key (sb_secret_...) aus. Der Publishable Key ist der Key deiner App. Der Secret Key ist der Admin-Key — er kommt niemals auch nur in die Nähe von Frontend-Code.
Lege im Projekt-Root eine Datei namens .env.local an:
VITE_SUPABASE_URL=http://127.0.0.1:54321
VITE_SUPABASE_ANON_KEY=sb_publishable_...your-key-here...Und den Client unter src/lib/supabase.ts:
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
import.meta.env.VITE_SUPABASE_URL,
import.meta.env.VITE_SUPABASE_ANON_KEY
)9. Die .clinerules-Datei — der am meisten unterschätzte Schritt
Lege im Projekt-Root eine Datei namens .clinerules an. Cline liest sie automatisch vor jeder Aufgabe, und sie macht den Unterschied zwischen einem Agenten, der deiner Architektur folgt, und einem, der improvisiert:
# Project rules
## Stack
- React + TypeScript + Vite
- Tailwind CSS v4 + shadcn/ui (components live in src/components/ui)
- Supabase for database, auth, and storage (client in src/lib/supabase.ts)
## Rules
- Use existing shadcn/ui components before writing custom ones.
- Never hand-write authentication logic; always use supabase.auth methods.
- All database schema changes go into SQL migration files via
`supabase migration new <name>` — never apply schema changes directly.
- After schema changes, apply with `supabase db reset`.
- Read environment variables only via import.meta.env.VITE_*.
- Keep components small; one component per file.
- Do not add new dependencies without asking first.Frontier-Modelle erschließen sich diese Konventionen oft selbst; kleine lokale Modelle brauchen sie schriftlich. Warum, siehst du gleich ganz konkret.
10. Versionskontrolle — dein Undo-Button für KI-Fehler
git init
git add -A
git status # check the list: .env.local must NOT appear (your keys stay out of git)
git commit -m "Project scaffold: Vite + React + Tailwind + shadcn + Supabase"Wenn eine KI deinen Code editiert, ist git dein Sicherheitsnetz: Mach nach jedem funktionierenden Feature einen Commit, und jedes KI-verursachte Chaos ist nur ein git checkout -- . vom Rückgängigmachen entfernt.
Stolperfalle #8 — Supabase-Temp-Dateien blähen deine Commits auf. Nach deinem ersten Feature-Commit fallen dir vielleicht Tausende eingefügte Zeilen aussupabase/.temp/...auf — interne Arbeitsdateien, die nicht in die Versionskontrolle gehören. Schließe sie einmalig aus:echo "supabase/.temp/" >> .gitignore, danngit rm -r --cached supabase/.tempund committen.
Phase 3: Das erste Feature — und was KI-Agenten bei Datenbanken falsch machen
Setup erledigt. Zeit zu viben. Mit laufendem supabase start und npm run dev öffnest du das Cline-Panel und promptest:
Create a todos feature: a migration for a `todos` table (id uuid pk default gen_random_uuid(), title text not null, done boolean default false, created_at timestamptz default now()), then a page using shadcn/ui components that lists, adds, and toggles todos via the supabase client.
(Prompts an die KI funktionieren übrigens am besten auf Englisch — deshalb bleibt dieser hier im Original.)
Cline schlägt Dateiänderungen vor, du genehmigst sie, und der Browser lädt per Hot Reload eine Todos-UI. Magisch — bis du versuchst, ein Todo anzulegen. Hier kommt der ehrliche Teil, den die meisten Tutorials überspringen. Mein erstes Feature scheiterte zweimal, auf zwei lehrreiche Arten:
Stolperfalle #9 — "Could not find the table 'public.todos'". Die UI existiert, aber die Datenbanktabelle nicht. Datenbanken ändern sich über Migrationsdateien — kleine SQL-Skripte insupabase/migrations/, die mitsupabase db resetangewendet werden. Mein lokales Modell hat die UI gebaut, aber die Migration ausgelassen (ja, trotz Rules-Datei — kleine Modelle machen das manchmal). Die Gewohnheit, die das jedes Mal auffängt: Prüfe nach jedem Feature, das Daten berührt, ob eine neue.sql-Datei insupabase/migrations/erschienen ist. Falls nicht, sag Cline: "Put the schema changes in a migration file viasupabase migration new." Dann mitsupabase db resetanwenden.
Stolperfalle #10 — "permission denied for table todos". Fortschritt — die Tabelle existiert jetzt — aber Postgres verweigert deiner App den Zugriff darauf. Supabase-Apps sprechen mit der Datenbank als eingeschränkte „anon"-Rolle, und neue Tabellen brauchen explizite Zugriffsrechte plus eine Row-Level-Security-Policy. Der robuste Fix ist eine Migration, die Erstellung und Berechtigungen zusammen erledigt. Lege eine mit supabase migration new create_todos an und gib ihr diese Form:create table if not exists public.todos (
id uuid primary key default gen_random_uuid(),
title text not null,
done boolean not null default false,
created_at timestamptz not null default now()
);
grant usage on schema public to anon, authenticated;
grant select, insert, update, delete on table public.todos to anon, authenticated;
alter table public.todos enable row level security;
drop policy if exists "dev allow all" on public.todos;
create policy "dev allow all" on public.todos
for all using (true) with check (true);Dann supabase db reset, Browser neu laden — und es funktioniert. Lege ein Todo an, lade die Seite neu, es bleibt bestehen. Öffne Studio, und da ist deine Zeile in Postgres. Das ist die komplette Kette, verifiziert: dein Prompt → lokale KI → Code + Migration → echte Datenbank → live UI.
(Diese „allow all"-Policy ist bewusst sperrangelweit offen — korrekt für lokale Entwicklung, wo der einzige User du selbst bist, und genau das, was durch echte Sicherheitsregeln ersetzt wird, bevor irgendetwas live geht. Das ist ein Thema für Teil 2.)
Stolperfalle #11 — doppelte Migrationen. Nach dem Fix hat mein Agent verspätet noch seine eigene Create-Table-Migration angelegt, die das nächstesupabase db resethätte crashen lassen (eine Tabelle anzulegen, die bereits existiert, ist ein Fehler). Wenn zwei Migrationen dieselbe Tabelle anlegen, lösche die überflüssige und führesupabase db reseterneut aus, um zu beweisen, dass der Satz gesund ist.
Committe den Meilenstein: git add -A && git commit -m "Add todos feature".
Wie tägliches Vibe Coding wirklich aussieht
Eine Quelle der Verwirrung, die es aufzuklären lohnt: VSCode bringt sein eigenes KI-Chat-Panel mit, und Cline fügt ein zweites hinzu. Die beiden haben nichts miteinander zu tun. Nutze ausschließlich das Cline-Panel — es ist das, das mit Ollama verbunden ist und das Dateien editieren und Befehle ausführen kann. Blende den eingebauten Chat aus und denk nie wieder darüber nach.
Das Lovable-Mapping, ein Bildschirm, zwei Hälften: VSCode mit dem Cline-Panel links, Browser mit deiner App rechts. Lovables Chat = Cline. Lovables Vorschau = localhost:5173. Lovables versteckter Code = sichtbar in deinem Editor, was ein Feature ist, kein Bug.
Der tägliche Rhythmus:
# session start
supabase start
npm run devDann die Schleife: ein Feature bei Cline beschreiben → die Diffs reviewen → genehmigen → zusehen, wie der Browser per Hot Reload neu lädt → falls Daten im Spiel waren, kurz in supabase/migrations nach einer neuen Datei schauen → testen → git add -A && git commit -m "feature". Wenn etwas schiefläuft, sag es Cline oder rolle mit git zurück. Am Sitzungsende supabase stop — was uns zur Hardware bringt.
Eine Anmerkung zum RAM (MacBook-Air-Besitzer, das ist für euch). Ollama mit einem 7b-Modell will 5–8 GB; der lokale Supabase-Stack nimmt 1,5–2,5 GB; Vite und dein Browser noch einmal 1–2 GB. Mit 16 GB koexistiert alles problemlos. Mit 8 GB nutzt du den Umschalt-Trick: supabase stop, während das Modell schwer am Generieren ist, supabase start, wenn du testen willst. Und drei Gewohnheiten, die speziell kleinen lokalen Modellen helfen: Halte Aufgaben klein (ein Feature pro Cline-Konversation, dann eine frische Aufgabe starten — lange Chats lassen kleine Modelle abbauen), nutze Clines Plan mode vor dem Act mode für alles Nicht-Triviale, und halte deine .clinerules aktuell, während das Projekt wächst.
Was du jetzt hast — und was als Nächstes kommt
Für den Preis eines Nachmittags und null Euro pro Monat betreibst du jetzt denselben Stack, den Lovable verkauft: einen KI-Agenten, der eine React + Tailwind + shadcn-App gegen eine echte Postgres-Datenbank baut, Live-Vorschau inklusive, komplett auf deinem eigenen Rechner. Plus drei Dinge, die Lovable dir nicht gibt: totale Privatsphäre, sichtbaren Code, der dir wirklich gehört und den du verstehst, und Leitplanken (git, Migrationen, Rules-Datei), wie sie professionelle Entwickler nutzen.
Alles bisher lebt auf localhost — nur für dich sichtbar. Teil 2 dieser Serie behandelt das fehlende Kapitel: Publishing. Wie du eine vibe-gecodete App live auf einen echten Cloud-Webserver bringst — GitHub für den Code, Vercel für das Frontend, Supabase Cloud für die Datenbank — wobei sich der gesamte Übergang von lokal zu live auf das Ändern von zwei Umgebungsvariablen und das Ausführen von zwei Befehlen reduziert. Und, ganz entscheidend, wie du diese sperrangelweit offene Entwicklungs-Policy durch echte Row-Level-Security-Regeln ersetzt, bevor deine App auf das öffentliche Internet trifft.
Bis dahin: supabase start, npm run dev — und bau was.
Dies ist Teil 1 der Serie „Vibe Coding auf eigene Faust". Teil 2: „Von Localhost zu Live: Wie du deine vibe-gecodete App auf einen Cloud-Webserver bringst."