This weekend I decided to upgrade my website, and in just a few hours I was able to completely refresh my visual identity using Lovable.
Clean, structured, with an AI-generated hero video — and without writing CSS by hand.
But before getting there, I had to solve a problem most people ignore in vibe coding:
Without structure, you build fast. And refactor twice as much later.
Here’s what I’ve learned using Lovable since August 2025 — and the template I created so I never have to start from scratch again.
⸻
The trap of vibe coding without a framework
Lovable is amazing. You describe what you want, it generates it. In minutes, you have something visual working.
The problem shows up around prompt 5 — when you haven’t defined colors, fonts, folder structure, or coding standards.
Lovable starts making decisions for you — and not always the same ones across prompts.
Result: hardcoded colors everywhere, duplicated components, and a structure no one can maintain.
The solution is not to use less AI. It’s to provide more context.
⸻
Define before you generate
3 mandatory questions:
1. Product — What and for whom? Problem, audience, North Star.
2. Design System — What will it look like? HSL tokens, typography, components. Everything before building any screen.
3. System Design — How will it work under the hood? Stack, architecture, database, deployment.
These are different things. Confusing them is one of the most common mistakes.
⸻
Design System ≠ System Design
Design System is the visual vocabulary: color tokens, typography, reusable components. How it looks.
System Design is the technical architecture: how the database connects to the frontend, how modules communicate. How it works.
On my site:
→ Design System: HSL tokens, Plus Jakarta Sans + Inter fonts, Button and Badge variants via CVA, glassmorphism, gradient text
→ System Design: React 18 + Vite + Supabase, feature-based architecture, Event Bus, Ports & Adapters
⸻
Why I did NOT use microservices
Lovable + Supabase is a modular monolith — and that’s the right decision.
Microservices solve operational scale problems for multiple teams with independent deployments. For an early-stage SaaS or personal site, they add complexity with zero return: service discovery, network latency, orchestration overhead.
What matters here is having well-isolated modules within the same process.
That’s exactly what feature-based architecture + Event Bus provides — separation of concerns without operational complexity.
Rule I follow:
Features never import each other directly. Communication happens through a typed Event Bus. External integrations go through Ports & Adapters.
⸻
SOLID in React — in practice
→ S: a component does one thing. SectionHeader only renders a header.
→ O: extension via CVA variants. Need a new button style? Add a variant. Don’t touch button.tsx.
→ L: Ports & Adapters enable substitution. Swap Supabase Storage for Cloudinary by changing an adapter.
→ I: granular hooks — useAuth, useOrganization, useFeatureGate. No “god hook” like useApp().
→ D: features depend on interfaces, not directly on Supabase.
⸻
The hero video? Also AI-generated
The hero background is a video created with PixVerse (app.pixverse.ai), using text-to-video with a futuristic/tech style.
Exported as .mp4 and used with video autoPlay muted loop, plus an overlay to ensure readability.
Cinematic visuals — no stock footage, no designer, no Adobe Premiere.
⸻
The result
→ Site: https://raphaelmoraes.dev/
→ Stack: React 18 + Vite + Tailwind + shadcn/ui + Supabase + Cloudflare + PixVerse
→ Time: just a few hours of structured vibe coding
I documented everything in a Playbook with 8 ready-to-use prompts for Lovable — including a full Design System, real tokens from the repo, pt-BR + en translations, SOLID checklists, and cross-cutting rules.
🔗 Site: https://raphaelmoraes.dev
📄 Full Playbook (Gist): https://gist.github.com/rdemoraes/e08d7318de3e3aa0e4c67d69fa1d0fa3
🎬 Hero video generated with: https://app.pixverse.ai
Top comments (0)