Prompt Architecture: How to Structure Your Codebase So AI Writes Better Code

The secret to good AI-generated code isn't better prompts — it's better architecture. Here's how to structure your codebase so the AI has the right context to write correct code with minimal guidance.

amejia
amejia
· 4 min read

Most people think the secret to good AI-generated code is better prompts. It’s not. The secret is better architecture. The same AI model generates dramatically different quality code depending on the structure of the project it’s working in. I’ve tested this repeatedly — same model, same prompt, different project structures — and the architecture wins every time.

I call this “prompt architecture”: organizing your codebase so the AI has the right context to generate correct code with minimal guidance.

The Context Window Is Your Design Constraint

An AI model generates code based on what it can see: the current file, any files you’ve included in context, and its training data. The quality of the output depends almost entirely on the quality of that context.

If the context includes a clean, well-typed, well-named file with 100 lines — the AI generates clean, well-typed, well-named code. If the context includes a messy 800-line file with mixed concerns — the AI generates messy, inconsistent code that matches the patterns it sees.

Your codebase is the prompt. Structure it accordingly.

Principle 1: Exemplar Files

For every “type” of file in your project — API routes, components, hooks, services, tests — maintain one exemplar that represents the ideal pattern. This file is the gold standard. When the AI needs to generate a new file of that type, point it to the exemplar.

My exemplar files are annotated with comments explaining why each decision was made, not just what the code does. The AI reads these comments and replicates the reasoning, not just the syntax.

// services/projects.service.ts (EXEMPLAR)
// 
// Pattern: Service files export async functions that return typed data.
// Each function handles one API call.
// Errors are caught and re-thrown as typed AppError instances.
// No UI logic, no state management — pure data operations.

import type { Project, CreateProjectInput } from '@/types/project';
import { AppError } from '@/lib/errors';

export async function getProjects(): Promise<Project[]> {
  const res = await fetch('/api/projects');
  if (!res.ok) throw new AppError('Failed to fetch projects', res.status);
  return res.json();
}

When I ask the AI to “create a service for managing team members,” it reads this exemplar and generates a file with identical structure, error handling, and typing conventions. No additional prompting needed.

Principle 2: Co-located Types

Types should live next to the code that uses them, not in a monolithic types/ folder. When the AI opens a service file, the types for that service’s data should be importable from a sibling file — not buried in a 500-line types index.

My structure: features/projects/types.ts next to features/projects/service.ts next to features/projects/hooks.ts. The AI opens any file in the feature folder and has complete type context within one directory traversal.

Principle 3: Naming as Documentation

The AI reads your file names and function names as context clues. Descriptive naming eliminates entire categories of errors.

  • useProjectListFilters() — the AI knows this hook manages filter state for a project list
  • formatCurrency(amount, locale) — the AI knows this is a pure formatting function
  • ProjectCard.tsx — the AI knows this renders a single project as a card component

Vague names like utils.ts, helpers.ts, or useData() give the AI no context clues, and it generates code that’s equally vague.

Principle 4: README Per Feature

Each feature folder gets a 10–20 line README that describes the feature’s purpose, data flow, and key decisions. This isn’t documentation for humans (though it helps) — it’s context for AI.

When I open a feature folder in Cursor and the README is automatically included in context, the AI understands the bigger picture before I ask my first question. It knows which API endpoints exist, how state flows through the feature, and what patterns to follow.

Principle 5: Constraint Files

A .cursorrules file (or similar) in the project root provides persistent context that shapes every AI response. I use mine to encode project-wide constraints:

# Project constraints
- Use TypeScript strict mode
- Components use Tailwind CSS only — no CSS modules or styled-components
- Data fetching through service files, never directly in components
- All components must accept a className prop for composition
- Error boundaries wrap every page component
- No barrel exports (index.ts re-exports) — import from source files directly

These constraints prevent the most common AI code drift: style system mixing, inconsistent data fetching patterns, and barrel export chains that obscure where code actually lives.

Principle 6: Small, Typed, Pure

The ideal file for AI consumption is small (under 150 lines), fully typed (TypeScript with strict mode), and pure (one clear responsibility, explicit inputs and outputs, no hidden side effects).

Files that match this profile get correct AI-generated modifications ~90% of the time. Files that don’t — large, loosely typed, with mixed concerns — get correct modifications maybe 40% of the time. That 50% accuracy gap is the difference between productive AI-assisted development and frustrating debugging sessions.

The Meta-Insight

Prompt architecture isn’t just about AI. Every principle listed here — exemplar files, co-located types, descriptive naming, feature READMEs, constraint files, small/typed/pure modules — also makes codebases better for human developers. New team members onboard faster. Code reviews are easier. Bugs are more isolated.

Optimizing for AI readability and optimizing for human readability are the same thing. A codebase that an AI can understand in 150 lines of context is a codebase that a human can understand in 5 minutes. This isn’t a coincidence — it’s the fundamental insight behind prompt architecture.