How to hide vibe code in web design.
AI can build you a website in an afternoon, and everyone can tell. Not from the code (nobody sees your code) but from the defaults: the purple gradient, the three feature cards, "Elevate your workflow ✨", cards flying in from the left.
This repo is what I learned taking two AI-assisted sites (burakicebe.com and a site for a local lawn care business) from "obviously generated" to designed. It has three parts:
| What | Use it for | |
|---|---|---|
| The guide | Eight short chapters: content, copy, colour, type, layout, motion, details, checking | Learning what gives a site away and what to do instead |
unvibe |
A zero-dependency CLI that scans your source for the tells, with line numbers and fixes | Catching defaults before you ship, locally or in CI |
quiet-motion |
React components: a 16px fade-up reveal, a masked heading rise, rolling text and a drafting cursor | Motion that feels designed instead of generated |
Plus a one-page checklist.
Every default is a tell. Replace each one with a decision.
- Never invent. No made-up stats, testimonials or placeholder names. Missing facts become TODOs that are hidden in production.
- Write like a person. No em-dashes in body copy, no "seamless", no emoji bullets, and buttons that name their action.
- One accent colour. No purple gradients, no gradient text, no glass, no blobs.
- Type with a point of view. Not Inter by default.
- Break the grid on purpose. No row of three identical icon cards.
- Quiet motion. Fade up 16px, never slide in from the sides. Nothing hidden without JavaScript. Everything off under reduced motion.
npx github:BuruCebe/unvibe ./srcHere it is on the deliberately bad fixture in this repo (trimmed):
packages/unvibe/test/fixtures/vibey/Hero.tsx
10 warn side-slide Content flying in from the sides on scroll is the most common 'vibe coded' motion.
fix: Fade up a few pixels (12 to 16px) instead, or reveal with a mask.
11 warn buzzword Marketing filler says nothing a visitor can check. "Elevate"
Elevate your workflow ✨
fix: Replace it with the specific thing: what it does, for whom, with what result.
13 warn em-dash Em-dashes in body copy are the single most recognised tell of generated text.
<p>Seamlessly build the future — trusted by 10,000+ happy customers.</p>
fix: Split the sentence, or use a comma, colon or parentheses.
15 error dead-link href="#" ships when a section was generated before anyone knew where it should go.
<a href="#">Get Started</a>
fix: Link somewhere real or remove the link.
1 files · 3 errors · 10 warnings · 5 notes
It exits with code 1 on errors, so you can add it to CI:
- run: npx github:BuruCebe/unvibe ./src --max-warnings 0It is not on npm yet. Each component is one file with no dependency besides React, so copy what you need from packages/quiet-motion/src (keep reduced.ts, they all use it).
// after copying packages/quiet-motion/src into lib/quiet-motion
import { Reveal, Rise, RollText, Cursor } from "@/lib/quiet-motion";
import "@/lib/quiet-motion/cursor.css";See the quiet-motion README for each component.
npm install
npm test # checker tests
npm run build # builds quiet-motion
npm run check # runs unvibe on this repo's own docs and componentsMade by Burak Cebe. MIT licensed.
Found a tell this misses? Open a new tell issue with a before and after, or see CONTRIBUTING.md to add the rule yourself. Changes are listed in the changelog.