"Write me a login page" → You get a beautiful mess. Inline styles, no error handling, hardcoded credentials, and a password field named p.

"Write me a login page" + the right context → You get something you'd actually ship. The difference? About 30 seconds of thinking about your prompt.

The SPEC Framework

I use a four-part structure I call SPEC. It works with every AI coding tool — Copilot, Cursor, Claude, local models via Ollama:

S — Situation

Tell the AI what project it's in and what conventions matter:

"I'm building a static blog using vanilla HTML and CSS. 
No frameworks. No build tools. The CSS uses custom 
properties for theming."

P — Problem

State the specific task. Be precise about inputs and outputs:

"I need a responsive card grid component that displays 
blog post previews. Each card shows: title, date, 
excerpt (max 2 lines), and category tags."

E — Examples

Show the AI what success looks like. Paste existing code from your project:

"Here's my current CSS variable system:
--bg: #f8f9fc;
--text: #1a1f2c;
--accent: #d97706;
--radius: 12px;

Here's how existing components are styled: [paste example]"

C — Constraints

Tell the AI what NOT to do. This is the most underused trick:

"Constraints:
- No JavaScript
- No Tailwind classes
- Must work in CSS Grid, not Flexbox
- Minimum touch target 44px on mobile
- No external dependencies"

Real Example: Before and After

Bad Prompt:

"Make a search bar"

Result: A generic input field with inline styles, an onclick handler that calls a function called search() that doesn't exist, and a magnifying glass emoji as the icon. Technically correct. Practically useless.

Good Prompt (Using SPEC):

"Situation: Static site, vanilla HTML/CSS, uses Inter font, 
dark/light themes via CSS custom properties.

Problem: Search input that filters a list of blog post 
cards by title. Should show/hide cards based on typed text.

Example: My CSS vars are --bg-card, --border, --text-soft, 
--radius-sm. Cards have class .post-card with h2 > a for titles.

Constraints: Under 20 lines of JS. No external libraries. 
Must be accessible (proper aria labels). Debounce the input."

Result: A perfectly styled, accessible search component that matches your existing design system and actually works.

Bonus Tips

  • Paste your existing code. The more context the AI has, the better it matches your style. Paste your CSS variables, your component structure, your naming conventions.
  • Ask for trade-offs. "What are the downsides of this approach?" forces the AI to think critically instead of just generating.
  • Iterate in small steps. Don't ask for an entire page. Ask for one component, review it, then ask for the next.
  • Say "no comments" or "minimal comments." AI loves to add a comment above every single line. Tell it to stop.

The Meta-Lesson

Good prompts are basically good technical specifications. If you can write a clear spec, you can get great output from AI. If your spec is vague, your code will be vague.

The irony: learning to write better prompts makes you a better developer, because it forces you to think clearly about requirements before touching code. AI hasn't replaced that skill — it's made it more valuable.