jjcandrive

Field note

I vibe-coded this site in a day

A non-developer's honest log of building a Next.js blog — wireframe to live domain — with an AI pair at the keyboard.

4 min read · Apr 20, 2026

I'm not a developer. I run a brand, I write, I market things. I read code the way I read recipes — slowly, and usually after something has gone wrong.

Yesterday I built and deployed this site, end to end, in about a day. Not because the build was trivial, but because I wasn't alone at the keyboard. I was vibe-coding — the ugly little phrase for working alongside an LLM in your terminal, describing what you want, reading what it ships, and pushing back when it drifts.

Here is the honest log.

The plan

I had written myself a Day 1 build guide: scaffold the project, wire routing, set up an MDX pipeline, drop in design tokens, layout components, OG images, ship to Vercel with a password gate. Eight steps, two to three hours budgeted. Reality was longer — but not by much.

The guide said Next.js 14. The project installed Next.js 16. That kind of mismatch is the whole story of working with model-written code: you have to know enough to smell when the guide is out of date.

What went smoothly

Scaffolding, routing, MDX, design tokens, header, footer, post layout — these came together one-to-one from the guide. I described the outcome, watched the code appear, spot-checked it in the browser. Good.

The first small win was the MDX pipeline. I wanted to drop a markdown file in a folder and have it become a page at /writing/<slug>. One npm install, a helper to read frontmatter, a dynamic route — and the first post rendered. Title parsed, body compiled, metadata in the browser tab. That was the moment I realised this was going to ship today.

What didn't

A few genuine stumbles, in order:

Next.js 16 breaking changes. params is now a Promise you have to await. middleware.ts is called proxy.ts. @vercel/og got rolled into next/og. None of this was in my guide. You feel your way by reading the bundled node_modules/next/dist/docs folder — the version of the docs that ships with your actual installed Next. That trick, I'll keep using.

Tailwind v4. There is no tailwind.config.ts anymore. Theme tokens live in CSS via an @theme directive. My guide assumed v3. Ten minutes of translation, then the rest of the step was fine.

DEPLOYMENT_NOT_FOUND. I pointed jjcandrive.com at Vercel in Namecheap, Vercel's edge answered, and the edge said, essentially, "I don't know which project to serve." The domain has to be added to a project, not just pointed at Vercel. A thirty-second fix in Settings → Domains. It cost twenty minutes of "is DNS broken?".

Hobby plan means no password protection. The guide's deploy step assumed a Pro plan. I wanted pre-launch gating, so instead we wrote a tiny proxy.ts that does Basic Auth when a SITE_PASSWORD env var is set, and no-ops when it isn't. Twenty lines of code. It works.

The first homepage was just an <h1>. The guide intentionally left content for Day 2. I'd forgotten, hit the live URL, saw a single word in serif, and stared for a second. Where's the design? On /writing/<slug>, where the post layout lived. An hour later I had a real homepage that surfaces the work.

The design-spec rewrite

Late in the day, I wrote a proper design system guide — colors, type scale, border weights (0.5px, always), sentence case, component recipes. Then I asked the AI to audit the existing code against the spec and rewrite anything that didn't match.

This was the most productive step of the day. Vibe-coding without a written spec gives you drift — close-enough implementations that compound into something generic. A written spec converts taste into test cases. The audit found about fifteen deviations in five minutes. All fixed in one commit.

If I do this again — and I will — I'll write the design spec before the layout components, not after.

What I actually did

Describe outcomes. Read the diff. Refuse the generic version. Push back when the instinct is to add three colors where one will do. The role is closer to editor than to coder.

The site is live and open. The source is on GitHub. The next post will probably be about writing the design spec, because that was the single highest-leverage document I made today.

One day, one person who doesn't know JavaScript. A dozen commits. Live.

Back to the notebook