DEV Community

Cover image for GitHub Spec-Kit: From Vibe Coding to Spec-Driven Development
Peter Saktor
Peter Saktor

Posted on

GitHub Spec-Kit: From Vibe Coding to Spec-Driven Development

AI coding agents are improving rapidly. Tools like Copilot, Codex, and Claude can generate large chunks of code, but without proper structure, this can quickly lead to messy and inconsistent implementations.

That’s where spec-driven development comes in.

By using the GitHub Spec-kit, you can move from "hoping for the best" to a controlled, logical development cycle where the AI works for you, not the other way around.

What is Spec-Kit?

Spec-kit is an AI prompting framework designed to integrate various coding agents (like Copilot, Claude Code, or Codex) into a structured workflow.

The core philosophy is simple: Start with a spec.

  1. The Spec: A high-level description of what you want to build, focusing on the "what" and "why" without technical implementation details.
  2. The Plan: A technical blueprint derived from the spec.
  3. The Tasks: A logical list of coding steps.
  4. The Code: The final implementation carried out by the agent.

Why use it?

If you’ve tried “vibe coding” with AI, you’ve probably seen this:

  • The agent goes off track
  • Code becomes inconsistent
  • Bugs appear in unexpected places
  • Everything feels loosely stitched together

Spec-Kit solves this by introducing structure.

Benefits

  • More control over AI output
    You clearly define what the agent should do before it writes code.

  • Consistency across teams
    Specs act as shared rules, especially valuable in team environments.

  • Traceability
    Specs are stored in your repository, so the AI has historical context.

  • Better alignment
    You can review plans and tasks before any code is generated.

Getting Started with Spec-Kit

The easiest way to get started is from the official repository:

👉 https://github.com/github/spec-kit

Spec-Kit uses uv, a fast Python package manager. You can initialize it within an existing project or scaffold a new one.

Create a new project

uvx --from git+https://github.com/github/spec-kit.git@vX.Y.Z specify init <PROJECT_NAME>
Enter fullscreen mode Exit fullscreen mode

Use it in an existing project

uvx --from git+https://github.com/github/spec-kit.git@vX.Y.Z specify init --here
Enter fullscreen mode Exit fullscreen mode

The uvx command runs a package without installing it, similar to npx for Node packages.

During setup, you’ll choose:

  • Coding agent (e.g., Copilot)
  • Script type (e.g., PowerShell)

The command creates two folders:

├── 📁 .github/     # Prepared prompts for your coding agent
└── 📁 .specify/    # Memory (constitution), scripts, and templates
Enter fullscreen mode Exit fullscreen mode
  • .github/ contains prompts for different development stages, available in your Copilot chat
  • .specify/memory/ holds your constitution.md file with ground rules
  • .specify/scripts/ contains PowerShell scripts that the agent runs
  • .specify/templates/ provides templates for specs, plans, and tasks

The Development Cycle

Here's the typical Spec-Kit workflow:

development cycle

Command Purpose
/constitution Set core binding principles for the entire application
/specify Create a high-level spec for a feature (creates new branch)
/clarify (optional) Agent asks questions about underspecified areas
/plan Add technical preferences (frameworks, libraries, etc.)
/tasks Turn the plan into a logical list of coding tasks
/analyze (optional) Check alignment across all artifacts
/implement Execute the tasks and build the feature

At the end of the cycle, you have a working feature based entirely on your initial spec. For each new feature, you walk through this process again, minus the constitution command, which you typically run once.

Real-World Demo: Refactoring an Azure Container App

I scaffolded a demo app called ACSdemo using GitHub Copilot CLI - an Azure Container App with this structure:

ACSdemo/
 ├── 📄 ACSdemo.slnx
 ├── 📄 README.md
 ├── 📄 docker-compose.yml
 ├── 📄 .dockerignore
 │
 ├── 📁 src/
 │   └── 📁 ACSdemo.Api/
 │       ├── 📄 Program.cs
 │       ├── 📄 WeatherForecast.cs
 │       ├── 📄 appsettings.json
 │       ├── 📄 appsettings.Development.json
 │       ├── 📄 Dockerfile
 │       ├── 📁 Controllers/
 │       │   ├── EventsController.cs
 │       │   ├── MessagesController.cs
 │       │   └── WeatherForecastController.cs
 │       ├── 📁 Models/
 │       │   ├── SendEmailRequest.cs
 │       │   └── SendSmsRequest.cs
 │       ├── 📁 Services/
 │       │   ├── ICommunicationService.cs
 │       │   └── CommunicationService.cs
 │       └── 📁 Properties/
 │           └── launchSettings.json
 │
 ├── 📁 dapr/
 │   └── 📁 components/
 │       ├── pubsub.yaml
 │       └── statestore.yaml
 │
 └── 📁 deploy/
     ├── main.bicep
     └── containerapp.bicep
Enter fullscreen mode Exit fullscreen mode

The goal:

  • Remove old REST controllers
  • Process Azure Service Bus events
  • Store data in Cosmos DB
  • Expose data via GraphQL

👉 Important constraint:
No manual coding, everything done by the AI agent.

Step 1: The Constitution Command

The constitution (constitution.md) outlines governing principles for your project, required frameworks, UX guidelines, testing expectations, etc.

Here's the prompt I used:

/speckit.constitution Create a project constitution for a microservice called "ACSdemo" with:

## Architecture & Design Patterns
- CQRS pattern with MediatR for all business operations
- Single-project structure with Domain/, Application/, Infrastructure/, Web/ folders
- GraphQL primary API using HotChocolate v15 with Apollo Federation

## Testing Requirements (NON-NEGOTIABLE)
- No unit tests, integration tests, or acceptance tests (demo app simplification)

## Communication & Integration
- Dapr pub/sub with Azure Service Bus, [Dapr.Topic()] attributes

## Technology Stack (exact versions)
- Runtime: .NET 10.0
- CQRS: MediatR 12.x
- GraphQL: HotChocolate 15.x
- Persistence: Azure Cosmos DB
- Messaging: Azure Service Bus via Dapr pub/sub
- Persistence: Azure Cosmos DB (Microsoft.Azure.Cosmos)
- Configuration: Azure App Configuration + Azure Key Vault
- Containerization: Docker (Linux), Azure Container Apps

## Infrastructure
- All Azure resources in Bicep templates under .infrastructure/. No manual portal changes.
- Configuration via Azure App Configuration with Key Vault for secrets.
- Environment values parameterized, never hardcoded.
Enter fullscreen mode Exit fullscreen mode

Output: A constitution with 6 core principles.

Pro tip: I deliberately pulled back on testing because this is a demo. In a real project, you'd add testing requirements to the constitutional prompt.

Step 2: The Specify Command

Instead of describing implementation, we define intent. We should focus on the what and the why, not the how:

/speckit.specify acsdemo-refactoring - This application needs refactoring. 
Delete EventsController, MessagesController, and WeatherForecastController.
Create a new EmailNotification controller that receives the 
Microsoft.Communication.EmailDeliveryReportReceived event from Azure Service Bus 
and saves it to Azure Cosmos DB. Users can then retrieve data via GraphQL queries.
Enter fullscreen mode Exit fullscreen mode

Output: A spec with 3 user stories (P1: data capture, P2: GraphQL queries, P3: cleanup) and 8 functional requirements.

Step 3: The Clarify Command (Optional but Valuable)

The clarify command instructs the agent to read the spec and find ambiguities, edge cases, or areas needing clarification. It asks you questions, and your answers get baked into the spec.

I ran it without any additional input:

/speckit.clarify
Enter fullscreen mode Exit fullscreen mode

The agent asked 5 questions, each with recommendations:

  1. How to store delivery status history? → Append a statusHistory array (Cosmos DB idiomatic approach)
  2. What partition key for Cosmos DB?email address (optimizes the main query path)
  3. Should GraphQL support pagination? → Offset/limit with default page size of 20
  4. Closed enum or open string for status values? → Open string (EmailDeliveryReportReceived is an external contract owned by Microsoft and can change)
  5. Maximum retry limit or defer to infrastructure? → Defer to Dapr/Service Bus config (YAGNI)

All questions answered, the spec was updated, and coverage was confirmed across all categories.

Key insight: This is where Spec-Kit shines. The agent thinks through edge cases you might have missed and documents the decisions.

Step 4: The Plan Command

Now we define the how.

Before planning, read your spec and make sure it's correct. All planning, research, task generation, and implementation will be based on this spec. Fix it now, not later.

/speckit.plan 

## 1. Cleanup & Deletion
- Delete Controllers/EventsController.cs, MessagesController.cs, WeatherForecastController.cs
- Remove associated DTOs

## 2. Domain Layer
- Create Domain/Entities/EmailDeliveryReport.cs with GuardClauses

## 3. Application Layer (CQRS & MediatR)
- Create SaveEmailDeliveryReport command (co-locate with handler + validator)
- Create GetEmailDeliveryReports query (co-locate with handler + validator)

## 4. Infrastructure Layer
- Update Cosmos DB configuration
- Update Bicep templates
- Configure Dapr pub/sub

## 5. Web Layer
- Create Dapr pub/sub endpoint in EmailNotificationController
- Create GraphQL queries with HotChocolate

## 6. Configuration & Wire-up
- DI registration via Configuration/ folder extension methods
Enter fullscreen mode Exit fullscreen mode

Output: A complete plan with research decisions, data models, GraphQL contracts, Dapr subscription specs, and a quickstart guide. All constitution checks passed.

Step 5: The Tasks Command

This command takes the plan and turns it into a series of tasks for the AI to follow. No additional input needed, just run it:

/speckit.tasks
Enter fullscreen mode Exit fullscreen mode

Output: 33 tasks across 6 phases, with clear parallelization opportunities:

Phase Tasks Focus
Phase 1: Setup T001–T003 .csproj upgrade, folder scaffold
Phase 2: Foundational T004–T006 Repository port, validation stub
Phase 3: US1 (MVP) T007–T015 Entity, command, controller
Phase 4: US2 T016–T020 GraphQL queries
Phase 5: US3 T021–T025 Legacy code cleanup
Polish T026–T033 Bicep, configuration

Step 6: The Analyze Command (Optional but Recommended)

The analyze command reviews all artifacts for inconsistencies, ambiguities, or coverage gaps. It's read-only, the agent won't make changes.

/speckit.analyze
Enter fullscreen mode Exit fullscreen mode

The analysis found 9 issues, including:

  • CRITICAL: Missing FluentValidation validators in query files (violates Constitution Principle I)
  • HIGH: TotalCount field in GraphQL schema couldn't be populated
  • HIGH: DI registration removal happening before dependent controllers were deleted

I asked for concrete remediation:

Suggest concrete remediation edits for the top issues
Enter fullscreen mode Exit fullscreen mode

The agent provided specific edits for each issue, which I applied directly to tasks.md.

Always run analyze before implementation. It catches constitutional violations and logical gaps that would cause runtime failures.

Step 7: The Implement Command

Finally, the agent runs through the task list and writes the code. You end up with a fully implemented feature that actually matches your initial vision.

/speckit.implement
Enter fullscreen mode Exit fullscreen mode

Result: Implementation complete — 33/33 tasks ✅

  • Build succeeded with 0 errors, 0 warnings
  • All legacy files deleted
  • Full infrastructure defined in Bicep
  • GraphQL endpoint working
  • Dapr pub/sub configured

Add a new feature

We can reuse our spec with a different plan, task list, and implementation. For example, if I want to implement a similar kind of feature using a different stack or database, I can use that spec file again because it does not contain any implementation details, only the required features from a user’s perspective. I could walk through the whole process again if I wanted to add another feature to the application.

I am going to start with a new spec. I do not need to change the constitution file because there have been no changes to the grounding principles of the app. We can jump straight to the specify command. We have a new branch and a new spec file inside the folder.

When Should You Use Spec Kit?

Use it when:

  • You want structured AI development
  • You work in a team environment
  • You need traceability and consistency

Avoid it when:

  • You’re building quick throwaway prototypes
  • The feature is too small (overhead isn’t worth it)

The Future of Spec-Kit

Spec-Kit is new and constantly evolving. New features are being added regularly, so keep up by checking the GitHub repo.

You can find the source code for the demo app here: ACSdemo

Top comments (0)