Skip to content

Building This Website with Vibe-Coding

November 29, 2025·5 min read
#vibe-coding#next.js#vercel#web-development#first-time

If you've been putting off building something because it's outside your comfort zone, this is what that gap actually looks like from the other side.

I'd never touched Next.js or React in production. Frontend was the gap. 48 hours later, this site exists: custom domain, dynamic social cards, blog system with custom MDX components. (Methodology at Building vibe-check.)

The interesting parts aren't the timeline. They're the two moments where things nearly went sideways, and what saved them.


The Near-Spirals

The OpenGraph Spiral

I'd never heard of OpenGraph images before this project. They're what generates social preview cards when you share a link.

17:26 aa00b8a: L480% trust First attempt. I asked Claude for the pattern, got opengraph-image.tsx, and trusted it would work.

17:42 e1447bb: L480% trust Still at L4. Added more metadata, enhanced the design. Looked great in my head.

17:45 b4d8796: L240% trust The break. Image wasn't rendering. I dropped to L2 and read the actual Satori docs.

> WARNING:

Satori has real CSS limitations. Gradients, certain flexbox patterns, many CSS properties just don't work. Error messages don't help.

The problem was obvious once I understood the constraint:

// BROKEN - Satori doesn't support this
backgroundImage: 'linear-gradient(...)'

// FIXED - solid colors work
background: '#0a0a0a'

17:54 3bc2c94: L480% trust Back to high trust. Redesigned with solid colors. Tested on opengraph.xyz. A+ rating.

Total spiral time: 28 minutes, 4 commits. Caught before it compounded.

The AI Slop Cleanup

20:08 b4707cb: I'm reading my own blog posts. Something's off.

The copy had that unmistakable AI feel. Correct, comprehensive, completely soulless. Every sentence the same length. No fragments. No personality.

01:27 78791a8: L120% trust Full rewrite at L1. Verify every line. If it sounded like ChatGPT wrote it, I deleted it.

The rule: bar conversation, not LinkedIn post. Short sentences. Fragments okay. Real voice.


What I Learned

Drop trust level when you're out of your depth

The OpenGraph spiral broke the moment I stopped prompting and started reading. Understanding the constraint broke the loop; more prompts wouldn't have.

L595% trust Setup and config: just run it. L480% trust Styling and layout: spot check. L360% trust New patterns: verify outputs. L240% trust Unfamiliar territory: verify everything.

Infrastructure stuff like DNS stayed at L5. Tailwind stayed at L4 because the concepts felt familiar. OpenGraph dropped to L2 because I needed to actually understand what Satori could do.

Fast feedback matters more than you'd expect

Every change had immediate feedback. npm run dev showed changes instantly, npm run build caught errors before deploy, Vercel previews tested production, opengraph.xyz validated social cards. Fast iteration catches mistakes before they compound.

AI-generated copy needs a human pass

AI writes correct, comprehensive, soulless prose. The 1:27am rewrite was the most important commit in the project. If your content reads like a LinkedIn post, it's not your voice yet.


The Core Insight

Working with AI on unfamiliar territory is actually a sweet spot. You can evaluate whether output is reasonable even if you couldn't have written it from scratch. The key is calibrating trust to the task.

I ran most of the work at L3-L4:

L480% trust Boilerplate and config: high trust, occasional spot checks.

L360% trust Custom components: verify the important outputs before moving on.

Gene Kim and Steve Yegge's book Vibe Coding nails the framing: AI reliability varies by task type, so calibrate trust accordingly.


The Build

Foundation (L5)

bash

npx create-next-app@latest personal-website --typescript --tailwind --app cd personal-website npx shadcn-ui@latest init

Setup, Vercel deployment, DNS: all pure L5. Push to main, auto-deploy, point nameservers. Standard infrastructure.

Pages and Components (L3-L4)

Described what I wanted, let Claude generate layouts. Checked that links worked, resized for mobile, moved on. Custom components took more attention at L3: describe, review, test in a post, iterate.

One gotcha: MDX can't parse angle brackets in regular text because it thinks they're JSX tags. Had to escape them or reword.

Blog System (L4)

Blog infrastructure was standard stuff: MDX parsing with next-mdx-remote, frontmatter with gray-matter, dynamic routes, reading time calculation. Claude knew all of it.


The Stack

LayerChoiceWhy
FrameworkNext.js 15 (App Router)Server components, great DX
StylingTailwind + shadcn/uiUtility-first, pre-built components
ContentMDX + gray-matterMarkdown with React components
DeploymentVercelZero-config, auto-deploys
DomainGoDaddy + Vercel DNSDomain + managed DNS

Try It

This approach works for anything unfamiliar:

bash

1. Start with high trust

npx create-next-app@latest my-site --typescript --tailwind

2. Run vibe-check as you build

vc --since "today"

3. Check your metrics periodically

vc

Start at L4-L5 for setup and boilerplate. Drop to L2-L3 when you hit something unfamiliar. If you get stuck in a spiral, stop prompting and start reading.

Understanding the constraint breaks the loop. More prompts usually don't.

If you've been putting off something unfamiliar, the gap is smaller than you think.