You ask an AI to build a user authentication feature. You get back code that works — for the happy path. The account lockout logic is missing. The token refresh flow doesn’t match your existing session model. The error responses use a different format to everything else in the codebase. You spend the next two hours in back-and-forth, patching the gaps one prompt at a time.
The problem isn’t the AI. The problem is that your original prompt was vague, and vague context produces vague output. Spec Kit is GitHub’s answer to this — a toolkit that forces you to produce structured, unambiguous context before any code gets generated.
What is Spec Kit?
Spec Kit is an open-source CLI that implements spec-driven development for AI coding assistants. Instead of jumping from requirement to prompt to code, it inserts two deliberate steps between them: specification and planning. The spec defines exactly what you’re building. The plan defines exactly how. The AI implements against that, not against a freeform prompt.
The output quality difference is meaningful. An AI given a two-sentence prompt and an AI given a structured spec with acceptance criteria, architectural constraints, and a dependency-ordered task list are not doing the same job. Spec Kit exists to consistently produce the second kind of context.
Why Structured Context Produces Better Output
AI coding assistants are good at filling in details when the shape of the problem is clear. They are poor at inferring requirements you haven’t stated. When you write a prompt like “build user authentication,” you know what you mean — JWT tokens, 24-hour expiry, lockout after 5 attempts, email verification. The AI doesn’t. It makes reasonable guesses, and some of them will be wrong for your specific context.
Spec Kit addresses this by separating two activities that most developers conflate: deciding what to build and building it. The spec and planning phases force the first activity to happen completely before the second begins. By the time code generation starts, the AI has:
- Your project’s architectural constraints and coding standards (the constitution)
- A precise description of the feature with acceptance criteria (the spec)
- Clarified answers to any ambiguities in the spec (the clarification step)
- A technical plan broken into ordered, dependency-aware tasks
That’s the context that produces output you don’t have to spend hours fixing.
The Workflow
Spec Kit organizes development into seven sequential commands, each building on the last.
1. /speckit.constitution — Establish principles
Before any feature work, define the rules that apply to your entire project. This becomes the persistent context the AI carries into every subsequent step.
# Project Constitution
## Architecture
- Hexagonal architecture: domain logic has no infrastructure imports
- Dependency injection for all services
- Result types for error handling, not exceptions
## Code Standards
- TypeScript strict mode
- All public methods have JSDoc comments
- No `any` types — use `unknown` and narrow
## Security
- Passwords hashed with bcrypt, minimum 12 rounds
- All endpoints require authentication unless explicitly marked public
- Input validated at the API boundary before reaching the domain
Write this once per project. It prevents the AI from making architecture decisions that contradict your existing patterns.
2. /speckit.specify — Define what you’re building
Write requirements without implementation details. Focus on behavior, not code.
# User Authentication Specification
## Overview
Users can register, log in, and manage their sessions.
## Requirements
### Registration
- Users register with email and password
- Email must be unique and correctly formatted
- Password must be at least 12 characters
- A verification email is sent after registration
- Unverified accounts cannot log in
### Login
- Users log in with email and password
- A JWT token is returned on success
- Accounts lock after 5 consecutive failed attempts
- Locked accounts return a clear error with unlock instructions
### Session Management
- Tokens expire after 24 hours
- Users can log out (invalidate their current token)
- Users can log out of all devices simultaneously
## Acceptance Criteria
- [ ] Registration creates an unverified user record
- [ ] Login fails for unverified accounts with a specific error code
- [ ] Account lockout activates after exactly 5 failed attempts
- [ ] Locked accounts cannot log in even with correct credentials
- [ ] Token expiry is enforced on all protected endpoints
- [ ] Logout from all devices invalidates every active token for the user
The acceptance criteria are the most important part. They define “done” precisely — both for the AI during generation and for you during review.
3. /speckit.clarify — Surface and resolve ambiguities
The AI reviews your spec and asks questions about anything unclear. This is where requirement gaps surface cheaply, before they become implementation bugs.
For the authentication spec above, it might ask:
- Does account lockout have a timeout, or does it require manual admin unlock?
- What happens to in-flight requests when a user logs out from all devices?
- Should the verification email resend endpoint be rate-limited?
You answer each question. The answers are appended to the spec and carried into planning.
4. /speckit.plan — Generate the technical plan
The AI produces an architecture and implementation plan based on your constitution and clarified spec. For the authentication feature, the output looks roughly like:
# Implementation Plan: User Authentication
## Components
### Domain Layer
- `User` entity with fields: id, email, passwordHash, verified, failedAttempts, lockedAt
- `AuthService` (input port): register, login, logout, logoutAll
- `UserRepository` (output port interface): findByEmail, save, updateFailedAttempts
### Application Layer
- `RegisterUseCase`: validate input → check email uniqueness → hash password → create user → send verification email
- `LoginUseCase`: find user → check verified → check locked → verify password → increment/reset failedAttempts → issue token
- `LogoutUseCase`: invalidate token record
- `LogoutAllUseCase`: invalidate all tokens for userId
### Infrastructure Layer
- `UserPostgresRepository`: implements UserRepository using TypeORM
- `JwtTokenService`: issues and validates JWT tokens
- `EmailService`: sends verification emails via SendGrid
### API Layer
- `POST /auth/register` → RegisterUseCase
- `POST /auth/login` → LoginUseCase
- `POST /auth/logout` → LogoutUseCase
- `POST /auth/logout-all` → LogoutAllUseCase
- `GET /auth/verify/:token` → VerifyEmailUseCase
## Dependencies
- `bcrypt` for password hashing
- `jsonwebtoken` for token issuance
- `class-validator` for input validation
5. /speckit.analyze — Validate the plan against the spec
The AI cross-references the plan against the spec and acceptance criteria, looking for gaps. Common catches: a use case that doesn’t map to an acceptance criterion, a component in the plan with no clear owner, a dependency the plan introduces that conflicts with the constitution.
6. /speckit.tasks — Break into ordered tasks
The plan becomes a dependency-ordered task list. Each task is small enough for a single implementation pass:
# Task List: User Authentication
## Phase 1: Domain
- [ ] 1. Create User entity with all fields and domain methods (isClosed, isLocked, canLogin)
- [ ] 2. Define UserRepository output port interface
- [ ] 3. Implement RegisterUseCase with validation and password hashing
- [ ] 4. Implement LoginUseCase with lockout logic
- [ ] 5. Implement LogoutUseCase and LogoutAllUseCase
- [ ] 6. Write unit tests for all use cases using stub repositories
## Phase 2: Infrastructure
- [ ] 7. Implement UserPostgresRepository with TypeORM
- [ ] 8. Implement JwtTokenService
- [ ] 9. Implement EmailService with SendGrid
- [ ] 10. Write integration tests for the repository layer
## Phase 3: API
- [ ] 11. Create AuthController with all five endpoints
- [ ] 12. Wire everything in the AuthModule
- [ ] 13. Write E2E tests for the full registration and login flows
7. /speckit.implement — Execute task by task
With the task list in hand, implementation proceeds task by task. Each prompt to the AI references the spec, the plan, and the specific task. The output is consistent because the context is consistent.
Getting Started
Install the Spec Kit CLI:
uv tool install spec-kit
Or run without installing:
uvx specify init my-project
Initialize a project for your AI assistant:
specify init my-project --agent claude-code
Spec Kit supports 18+ AI assistants — Claude Code, GitHub Copilot, Cursor, Gemini, Windsurf, Aider, and more. The --agent flag configures which assistant’s conventions are used for the generated artifacts.
When It’s Worth the Overhead
The workflow adds real upfront time. Writing a constitution, spec, and plan before touching code takes 30–60 minutes for a non-trivial feature. That investment makes sense when:
- The feature has multiple interacting components
- The requirements have edge cases that are easy to miss
- Multiple developers will work on the feature or read the output
- You want documentation that reflects what was actually decided, not reconstructed after the fact
It’s overkill for a single-endpoint change, a bug fix, or exploratory work where the requirements will change as you discover the problem. Use it when the cost of implementation mistakes is higher than the cost of planning upfront — which for most production features, it is.
Conclusion
The inconsistency most developers experience with AI code generation is not a capability problem — it’s a context problem. AI produces better output when given better input, and Spec Kit is a systematic way to produce better input every time.
The seven-step workflow might look like ceremony. In practice, the constitution and spec write themselves once you know the feature. The planning and task steps are where the real value is: gaps surface before they become bugs, and the task list gives the AI a scope it can execute precisely rather than a vague goal it has to interpret.
More info: github.com/github/spec-kit
