Spec-Driven Development
A development approach where written specifications — not prompts, not conversations — are the source of truth that drives code generation, testing, and verification.
What is it?
Spec-driven development (SDD) is a way of building software where you write down what you want before you build it. Not in vague terms, but in precise, testable descriptions of behaviour. These written specifications become the single source of truth: the code must match the spec, and the spec must match the intent.
This matters especially in the age of AI-assisted development. When an AI coding assistant generates code, it needs clear instructions to produce correct results. A well-written specification acts as those instructions — it tells the AI (or a human developer) exactly what the software should do, what inputs it accepts, what outputs it produces, and how it should handle edge cases.
SDD is not the same as waterfall (where you write everything upfront before building anything). Instead, specifications are written iteratively — one feature at a time, one vertical slice at a time. You write a spec for the next piece, build it, verify it against the spec, then write the spec for the next piece.
The core insight, articulated by GitHub’s Spec Kit team: “We’re moving from ‘code is the source of truth’ to ‘intent is the source of truth.‘” The specification captures intent in a way that survives context resets, team handoffs, and the passage of time.
In plain terms
Spec-driven development is like building a house from blueprints. You don’t just tell the builders “make me a nice house” and hope for the best. You draw detailed plans showing room dimensions, materials, wiring, and plumbing. The builders follow the plans, and inspectors verify the result matches them. The blueprints are the source of truth, not the builder’s memory.
At a glance
The document chain (click to expand)
graph TD A[Rough Idea] -->|clarify intent| B[PRD] B -->|define behaviour| C[Specification] C -->|order the work| D[Plan] D -->|break into units| E[Tasks] E -->|implement and verify| F[Code] F -->|validates against| C style C fill:#4a9ede,color:#fffKey: Each level adds precision. The PRD describes what and why. The Specification describes how it should behave. The Plan orders the work. Tasks are atomic units. Code is grounded in all of the above. The arrow from Code back to Specification shows that the spec is used to verify the code, not the other way around.
How does it work?
SDD follows a chain of documents, each adding precision to the one before it. The chain is not rigid — you can skip levels for simple features or add levels for complex ones.
1. The PRD (Product Requirements Document)
The first written artifact. It captures what you’re building and why. It’s human-readable, non-technical, and focused on the problem being solved and the user’s needs.
A PRD answers: What problem are we solving? For whom? What does “done” look like?
Concept to explore
See prd for how to write effective product requirements documents.
2. The specification
The heart of SDD. A specification describes how the software should behave in precise, testable terms. It includes:
| Part | What it defines | Example |
|---|---|---|
| Inputs | What the system accepts | ”A search query string, 1-200 characters” |
| Outputs | What the system returns | ”A JSON array of matching items with title, id, and score” |
| Behaviour | What happens in between | ”Items are ranked by relevance score, descending” |
| Edge cases | What happens when things go wrong | ”Empty query returns 400 Bad Request” |
| Acceptance criteria | How to verify correctness | ”Given a query matching 3 items, returns exactly 3 results” |
Think of it like...
A recipe in a cookbook. It doesn’t just say “make a cake.” It lists exact ingredients, quantities, temperatures, and timing. Anyone following the recipe — human or AI — should produce the same result. The recipe is testable: the cake either rises or it doesn’t.
Example specification (click to expand)
Feature: Search endpoint
Endpoint:
GET /api/items?q={query}Inputs:
q(string, required): Search query, 1-200 charactersOutputs:
200 OK: JSON array of{ id, title, score }sorted by score descending400 Bad Request: If query is empty or exceeds 200 charactersAcceptance criteria:
- A query matching 3 items returns exactly 3 results
- Results are sorted by score, highest first
- An empty query returns 400 with an error message
- A query with no matches returns 200 with an empty array
3. The plan
Specs tell you what to build. The plan tells you in what order. It sequences tasks so that dependencies are respected and each step produces a verifiable result.
Example plan (click to expand)
- Create database migration for
itemstable- Seed the table with test data
- Build the search API endpoint
- Write tests for all acceptance criteria
- Build the frontend search component
- Integration test: frontend calls API, displays results
4. The executable spec
A well-written specification isn’t just documentation — it’s executable. Acceptance criteria become automated tests. Input/output definitions become type checks. Invariants become assertions. The spec and the code verify each other.
This means the spec is never “stale” — if the code changes in a way that violates the spec, the tests fail. If the spec changes, the tests update to match, and the code must follow.
Concept to explore
See acceptance-criteria for how to write criteria that translate directly into automated tests.
SDD vs vibe coding vs waterfall
| Approach | Specification | Iteration | Risk profile |
|---|---|---|---|
| Waterfall | Complete upfront, all at once | None until end | Late discovery of problems |
| vibe-coding | None (prompt-based) | Constant | Drift, inconsistency, tech debt |
| Spec-driven | Per-slice, iterative | Slice by slice | Balanced: structured but adaptive |
The key distinction
SDD is neither waterfall (write everything upfront, then build) nor pure vibe coding (describe and hope). It’s iterative specification: write a spec for the next slice, build it, verify it, then spec the next slice.
Why do we use it?
Key reasons
1. Clarity before code. Writing a spec forces you to think through what you actually want before building it. Most bugs come from unclear requirements, not bad code. A spec eliminates ambiguity before it becomes a problem.
2. AI guidance. AI coding assistants produce dramatically better code when given precise specifications. Instead of interpreting a vague prompt, the AI follows a detailed contract. The spec acts as a bridge between human intent and machine output.
3. Verifiability. Acceptance criteria in a spec translate directly into tests. You can automatically verify whether the code matches the intent. This is impossible without a written spec — you’d be testing against your memory of what you wanted.
4. Surviving context loss. Conversations and prompt history get lost. Team members forget decisions. A written spec is version-controlled, searchable, and permanent. It survives context resets, team handoffs, and time.
When do we use it?
- When building features that must be correct (not just functional)
- When working with AI coding assistants — specs dramatically improve output quality
- When a project will span multiple sessions — specs preserve intent across context resets
- When multiple people (or agents) will work on the same codebase
- When you need to verify that what was built matches what was intended
Rule of thumb
If you’d be upset to discover the feature was built wrong after it’s done, write a spec first. The spec is cheaper than rebuilding.
How can I think about it?
The blueprint and the building inspector
A building blueprint is a specification. The architect draws it (writes the spec). The builders follow it (write the code). The building inspector checks the result against the blueprint (runs the tests). If the inspector finds a wall where a door should be, the blueprint settles the dispute — not the builder’s memory.
- Blueprint = specification document
- Architect = the person defining requirements
- Builder = the developer (or AI) writing code
- Inspector = automated tests
- The blueprint settles disputes = the spec is the source of truth
The sheet music and the orchestra
Sheet music is a specification for a musical performance. The composer writes it with precise notation — which notes, which instruments, which tempo, which dynamics. The conductor interprets it, and the orchestra performs it. If a musician plays the wrong note, the sheet music is the authority.
- Sheet music = specification
- Composer = the person defining intent
- Conductor = the plan (ordering and coordination)
- Musicians = developers or AI agents implementing the spec
- Recording = the final code
- Music critic comparing to the score = automated tests
Without sheet music, the orchestra can still play — but they’ll drift apart, and no two performances will be the same.
Concepts to explore next
| Concept | What it covers | Status |
|---|---|---|
| prd | Product Requirements Documents — capturing what and why | stub |
| technical-specification | Writing precise, testable behaviour descriptions | stub |
| architecture-decision-records | Recording why you chose one approach over another | stub |
| acceptance-criteria | Writing criteria that translate directly into tests | stub |
Some of these cards don't exist yet
They’ll be created as the knowledge system grows. A broken link is a placeholder for future learning, not an error.
Check your understanding
Test yourself (click to expand)
- Explain the difference between spec-driven development and waterfall. Why isn’t SDD just “write documents first, build later”?
- Name the levels of the document chain (from rough idea to code) and describe what each level adds.
- Distinguish between a PRD and a specification. What questions does each one answer?
- Interpret this scenario: a developer builds a search feature. It works, but it returns results sorted alphabetically instead of by relevance. How would a specification have prevented this?
- Connect spec-driven development to vibe-coding. When would you use each approach, and how can they complement each other?
Where this concept fits
Position in the knowledge graph
graph TD ID[Iterative Development] --> SDD[Spec-Driven Development] ID --> WS[Walking Skeleton] ID --> VS[Vertical Slices] ID --> VC[Vibe Coding] SDD --> PRD[PRD] SDD --> TS[Technical Specification] SDD --> ADR[Architecture Decision Records] style SDD fill:#4a9ede,color:#fffRelated concepts:
- vibe-coding — the unstructured counterpart; SDD evolved as a response to vibe coding’s limitations
- walking-skeleton — the first spec often defines the skeleton’s architecture
- vertical-slices — each slice gets its own specification and acceptance criteria
Further reading
Resources
- Spec-Driven Development and Agentic Coding (Vishal Gandhi) — The definitive practitioner account of SDD workflow
- Spec-Driven Development: Markdown as a Programming Language (GitHub Blog) — GitHub’s toolkit and methodology for SDD
- Understanding Spec-Driven Development: Tools (Martin Fowler) — Comparing Kiro, spec-kit, and Tessl
- Spec-Driven Development vs. Vibe Coding Fully Explained (Zencoder) — Side-by-side comparison with practical examples
- From Vibe Coding to Spec-Driven Design (Medium) — The transition from unstructured to structured AI development