Spec-Driven Development in Practice: A Walkthrough with Spec Kit

Introduction
As organizations and engineering teams adopt AI coding agents to accelerate output, spec-driven development (SDD) has emerged as a way to code more responsibly, steering the models in the direction you actually want them to go.
As attractive as Vibe Coding might sound, it's only viable for quick MVPs and prototypes. When you're building critical systems and enterprise solutions, engineers still need to guarantee code quality, meet security requirements, keep documentation up to date, and keep all the stakeholders in sync with the project status and health.
SDD takes a step back and tries to involve the AI coding agents in every phase of the software development lifecycle (SDLC), not only coding. That way the model ends up with all the required context to build a story or feature. If you want to understand the difference between Vibe Coding and SDD more deeply, check my previous article: Vibe Coding vs. Spec-Driven Development.
The SDLC phases covered by SDD:
Why I Tried Spec Kit
I had been building features on this blog by just prompting Claude directly. Describe the feature, iterate on the output, ship. It worked well enough for small changes, but for anything non-trivial I kept running into the same problems: scope creep mid-session, ambiguous requirements only noticed after implementation, and no artifact left behind to explain why a decision was made.
I wanted to try SpecKit to get hands-on experience with a more disciplined approach. Given the growing trend of AI-assisted development, I figured now was the right time to learn SDD properly rather than continue vibe coding.
How It Works (High Level)
SpecKit (or SDD) is used to:
- Define a feature before coding
- Clarify ambiguous requirements early
- Generate planning and tasks artifacts
- Feed the implementation learnings back into the spec and constitution (project memory)
SDD is more than a code generation workflow. The useful part is this iteration loop:
- Capture the intent (Requirements)
- Remove Ambiguity (Analyze & Clarify Gaps)
- Create a Plan (Project Phases, Sprints, Epics, Tasks)
- Implement (Actually code)
- Update the spec with what was learned
- Update the task and project status
- Update the constitution (memory) if a rule should become permanent across the entire project
One-Time Setup
1. Install and initialize Spec Kit
Install SpecKit in an existing project.
brew install uv
uvx --from git+https://github.com/github/spec-kit.git specify init --hereDuring setup, I selected the following options, but do experiment with different AI models:
- AI assistant:
claude - script type:
sh
After the speckit initial setup is completed, this is the expected result.
# claude specific commands you can now use to do SDD development
.claude/
└── commands/
├── speckit.analyze.md
├── speckit.checklist.md
├── speckit.clarify.md
├── speckit.constitution.md
├── speckit.implement.md
├── speckit.plan.md
├── speckit.specify.md
├── speckit.tasks.md
└── speckit.taskstoissues.md
.specify/
├── memory/
│ └── constitution.md # project memory (rules, guidelines, constraints)
├── scripts/ # these scripts are what speckit uses to help automate the SDD process
│ └── bash/
│ ├── check-prerequisites.sh
│ ├── common.sh
│ ├── create-new-feature.sh
│ ├── setup-plan.sh
│ └── update-agent-context.sh
└── templates/ # these are the default speckit templates used to create MD files. I did not touch these for the experiment, but plan to refine these for my own customizations
├── agent-file-template.md
├── checklist-template.md
├── constitution-template.md
├── plan-template.md
├── spec-template.md
└── tasks-template.mdThe Workflow I Followed
2. Define the constitution first
Before writing the first spec, encode the project rules that should guide all future work.
/speckit.constitution This is a Next.js blog for a software developer. The layout is in /src/layouts. The React components in react are in /src/components. Any business logic or server side logic is in src/services. Web pages and APIs are in /pages. The blog content, in MDX format, lives in /src/content. The UIUX design system is in docs/knowledge-base/ui/design-system.md. Additional documentation about the project is in /docs/knowledge-base. We are trying to not introduce any new dependencies unless needed.Then review and edit .specify/memory/constitution.md
3. Create the feature spec
Start a new feature with a detailed feature prompt using the command /speckit.specify
/speckit.specify I want to build a classic instagram mural on my website. The new page should be in /moments route. The moments page should match the themes (light/dark) defined on my website. It should contain a instagram like grid of photos. The grid should be mobile responsive. When you click in a photo, a modal (80% width of the screen) should open to display the image on the left side, and on the right there is some information about that photo (location, description, date). The /moments page should load data from a yml file moments.ymlExpected outputs:
- a feature branch such as
001-moments-photo-grid - The following files are created
specs/
└── commands/
├── 001-moments-photo-grid/
├── spec.md
├── checklists/requirements.mdImportant habit:
- be overly specific in the initial prompt
- immediately review
spec.md - add missing functional requirements before moving on
4. Clarify ambiguity before planning
Use the /clarify command to force decisions on UX, behaviour, data shape, and boundaries.
/speckit.clarify Review specs/001-moments-photo-grid/spec.md and identify gaps, ambiguity, and missing decisions.Typical output:
- guided questions with recommended options
- decisions that materially change complexity
- direct spec updates after answers are given
Example:
Question 1 o 5
Category: Interaction & UX Flow — Modal navigation scope
The spec defines opening a photo modal but doesn't address whether visitors can move between photos without closing and reopening. This is a significant scope decision —
it materially changes the complexity of the modal component.
Recommended: Option B — Prev/next navigation buttons in the modal. This is the expected Instagram-style pattern and avoids friction of closing/reopening. The incremental
complexity is low and delivers a noticeably better browsing experience.
┌────────┬──────────────────────────────────────────────────────────────────────────┐
│ Option │ Description │
├────────┼──────────────────────────────────────────────────────────────────────────┤
│ A │ No navigation — visitor must close modal and click the next photo │
├────────┼──────────────────────────────────────────────────────────────────────────┤
│ B │ Prev/next arrow buttons inside the modal to move between photos │
├────────┼──────────────────────────────────────────────────────────────────────────┤
│ C │ Keyboard-only navigation (left/right arrow keys) without visible buttons │
└────────┴──────────────────────────────────────────────────────────────────────────┘
You can reply with the option letter (e.g., "A"), accept the recommendation by saying "yes" or "recommended", or provide your own short answer./clarify resolved things like:
- modal prev/next navigation
- hover behaviour on thumbnails
- alt text fallback rules
- load-more behaviour
- pagination and scroll behaviour
- whether modal navigation spans all moments or only currently loaded ones
Rule:
- do not go to planning while the spec still contains meaningful ambiguity
5. Generate the implementation plan
Once the spec is stable enough, create the plan.
/speckit.plan Consult constitution.md, README.md, and specs/001-moments-photo-grid/spec.md.Expected outputs:
specs/
└── 001-moments-photo-grid/
├── contracts/
│ └── moments-yml-schema.md
├── data-model.md
├── plan.md
├── quickstart.md
├── research.md
├── spec.md
└── tasks.mdThe plan did two useful things:
- translated the spec into concrete architecture for this codebase
- ran a constitution check before implementation
6. Generate task breakdown
After planning, create executable tasks.
/speckit.tasks Generate tasks from specs/001-moments-photo-grid/plan.md.Expected output:
specs/
└── 01-moments-photo-grid/
├── tasks.mdWhat to look for:
- tasks grouped by user story
- dependency order
- parallelizable work marked clearly
- testing and validation tasks included
7. Run analyze before coding
Use /analyze as a guardrail check before implementation.
/speckit.analyze Review the spec, plan, and tasks for constitution violations, hidden complexity, or weak assumptions.Expected result:
- refinements to
spec.md,plan.md, andtasks.md - confirmation that the planned solution still respects repo constraints
/analyze updated the following files
specs/
└── 001-moments-photo-grid/
├── spec.md
├── plan.md
├── tasks.md8. Implement from the task list
Once the task list is credible, implement against it using the /implement command.
/speckit.implement Implement the tasks from the file specs/001-moments-photo-grid/tasks.md.The first implementation pass created or updated the following code:
├── meta/
│ └── moments.yml
├── src/
│ ├── __tests__/
│ │ └── moments.test.ts
│ ├── components/
│ │ ├── MomentModal.tsx
│ │ └── MomentsGrid.tsx
│ │ └── Navigation.tsx # updated
│ ├── pages/
│ │ └── moments.tsx
│ └── service/
│ └── moments.ts
└── e2e/
│ └── moments.spec.ts
├── specs/
│ ├── 001-moments-photo-grid/
│ └── tasks.md # marked tasks as completeThe Important Part: Iterate After the First Pass
The biggest practical lesson is that the first implementation is never the final spec. Some requirements only surface after seeing the feature working.
9. Human-test the feature
After implementation:
- run the UI
- test the main flow manually
- identify what feels missing, awkward, or too rigid
From the human tests, these new requirements surfaced:
- the
/momentspage also needed the site background animation - a moment should support multiple photos like a carousel
- multi-photo moments needed a visual indicator in the grid
- the modal needed carousel navigation
- the data model needed to change from one photo to a list of photos
Rule:
- treat the first implementation as a learning pass, not the last word
10. Update the spec with what you learned
After the feature exists, go back and update the spec to reflect product learnings.
Based on the conversation, encode the learning and the experience pieces (NOT THE TECHNICAL DETAILS) into specs/001-moments-photo-grid/spec.md for the current feature. Then convert those learnings into functional requirements.- post-implementation learnings were added to
spec.md - new functional requirements captured the carousel behavior and related UX rules
This step matters because it turns implicit product judgment into explicit documentation.
11. Update the constitution if the story teaches a reusable rule
Some learnings belong in the feature spec only. Others should become project-level rules.
/speckit.constitution From specs/001-moments-photo-grid/spec.md, is there anything that should be added to the constitution?The new rule/constraint was added to the constitution.md file:
- reusable SVG icons should live in
src/components/icons/
Rule:
- only update the constitution when a lesson should apply to future stories
- do not fill the constitution with story-specific details
Minimal Command Sequence
If you take nothing else from this post, this six-command loop is the core of the workflow:
/speckit.specify # create a new story/feature (requirements)
/speckit.clarify # analyze and identify gaps
/speckit.plan # create the solutions design and plan
/speckit.tasks # break down plan into tasks
/speckit.analyze # double check for any gaps, do constitution checks
/speckit.implement # allow your agent to finally start codingThen do the manual loop: human test, refine, update the spec, and update the constitution if a durable rule emerged.
Practical Rules For Future Stories
- start with the constitution, not the spec (provide context first)
- make the initial prompt concrete enough that the generated spec is testable
- review and edit
spec.mdmanually before clarify - use clarify to force product decisions early
- do not skip analyze
- implement from
tasks.md, not from memory - after shipping the first pass, update the spec with product learnings
- only promote durable lessons into the constitution
- keep commits aligned to workflow phases so the story stays reviewable
Suggested Commit Cadence
Another step that worked well for me is to commit at every step of the SDD workflow. This way, we have a traceable change history from ideation and requirement gathering all the way to implementation and refinement.
- init spec-kit
- create constitution
- create initial spec 001
- update spec after manual review
- clarify round (as many rounds as needed)
- generate plan
- generate tasks
- run analyze
- implement first pass
- implement improvements found in testing
- update spec with learnings
- update constitution if needed
- write or update supporting documentation
What Spec Kit Produced For Spec 001
The 001-moments-photo-grid story generated the following artifact set:
specs/
└── 001-moments-photo-grid/
├── checklists/
│ └── requirements.md
├── contracts/
│ └── moments-yml-schema.md
├── data-model.md
├── plan.md
├── quickstart.md
├── research.md
├── spec.md
└── tasks.mdHow This Scales Beyond Solo Work
This experiment worked well as a solo developer, but the workflow maps naturally onto team roles too. The entire documentation and decision trail lives in Git, which means it can become a shared source of truth. Product Owners can review and approve requirement changes through pull requests. Developers work from a spec that has already been agreed upon, rather than interpreting a Slack message. Architects can validate the plan before any code is written.
The key insight is that the artifacts SpecKit generates are not just inputs to the AI, they are the project's paper trail. That matters as much in a team setting as it does when you are working alone.
Final Takeaway
The best use of Spec Kit is to make feature intent explicit, pressure-test ambiguity before coding, and then capture what implementation taught you so the next story starts from a better baseline.
That is the core value of the workflow: the feature is no longer just code. It also has a decision trail. It's documented.
Changelog (1)
- Fix typos and grammar errors throughout the post.