Spec-kit Preset in Practice — Embedding Team Engineering Standards into the SDD Workflow
Background
In my previous article, I shared how to extend the standard SDD workflow defined by spec-kit through the extension mechanism. That workflow is usually organized as:
spec -> plan -> tasks -> implement
In this article, I will continue discussing the important topic of “customizing SDD”, but from a different angle.
Instead of extending the SDD workflow from the outside with extension, let’s focus on the four core steps mentioned above. These steps are the real center of software engineering work. However, every developer and every team may have very different styles, standards, and expectations for these steps, right?
That is why customization for these core steps is a real engineering need. The preset mechanism in the spec-kit framework is designed to solve exactly this problem.
After reading this post, you can understand:
- How
spec-kitorganizes commands and templates. - What a
presetis used for. - How a
presetcustomizes the standard SDD workflow. - How the built-in
leanpreset works as a practical example.
Reviewing How spec-kit Works
First, let’s quickly review how the spec-kit framework works.
After a project is initialized with spec-kit, it usually gets two core types of components:
- Commands: Commands define the behavior of the coding agent. They are instruction files. For example, the instruction file behind
speckit.specifytells the agent what steps to follow, which files to read, which files to write, and so on. Of course, commands may appear in different forms depending on the coding agent selected by the developer. For GitHub Copilot, they are custom agents and custom prompt files. For Cursor, they are agent skills. For Claude Code, they are command files. But at the abstract level, we can call all of them commands. - Templates: Templates define the format and content outline of documents generated by the coding agent at different stages. For example,
spec-template.mddefines the structure and requirements of thespec.mddocument generated during thespecifystep.
In the standard workflow defined by spec-kit, each step has its own command and template files.
For example, when using GitHub Copilot, the project structure generated by spec-kit looks roughly like this:
├───.github
│ └───prompts
│ plan.prompt.md
│ specify.prompt.md
│ tasks.prompt.md
│ └───agents
│ plan.agent.md
│ specify.agent.md
│ tasks.agent.md
│
└───.specify
├───memory
│ constitution.md
├───scripts
│ └───powershell
│ check-task-prerequisites.ps1
│ common.ps1
│ create-new-feature.ps1
│ setup-plan.ps1
│ update-agent-context.ps1
│
└───templates
agent-file-template.md
plan-template.md
spec-template.md
tasks-template.md
So the core working principle of spec-kit is quite clear:
It runs the corresponding commands, executes the built-in SpecKit scripts when needed, fills the generated content into templates, and finally produces spec documents that match your project requirements.
Great, right? The design separates agent behavior from document structure, which makes customization much easier.
Customizing Commands and Templates with preset
preset is one of the important mechanisms provided by the spec-kit framework. It allows us to customize each step of the standard workflow.
Let’s see how it works in the following sections.
Adding a preset
Each preset is like a software package. It contains code and files. Developers can create their own preset, publish it, and let the community use it.
You can use the following command to search for existing presets:
specify preset search
From the result, we can see that there are currently 26 presets registered in the spec-kit project. One of them is built into the project, called lean, and the others are contributed by the community.
You can use the following command to add a built-in preset:
specify preset add
For community presets, you can use the --from parameter to specify the package link.
How preset works
As we mentioned above, each step of the standard workflow is defined by commands and templates. So the working principle of preset becomes easy to understand:
Get JingJing (Chris) Bao’s stories in your inbox
Join Medium for free to get updates from this writer.
It uses custom commands and templates to replace or override the default behavior.
However, preset handles commands and templates in slightly different ways:
- Commands: A
presetcommand replaces the system default command during the preset installation process. - Templates: A
presettemplate does not directly replace the system default template. Instead, both templates exist at the same time. Whenever the coding agent needs to reference a template file,spec-kitdynamically selects the proper template at runtime based on priority. In general, the template from thepresethas higher priority.
This is a smart design, right? Commands are replaced when the preset is installed, while templates are selected dynamically when the workflow runs.
Breaking down the preset structure
Next step, let’s use the built-in lean preset in spec-kit to understand how to develop a preset.
As a software package, a typical preset structure looks like this:
my-preset/
├── preset.yml
├── README.md
├── commands/
│ ├── speckit.specify.md
│ └── speckit.plan.md
└── templates/
├── spec-template.md
├── plan-template.md
└── tasks-template.md
The core file here is preset.yml. It is the declaration file that connects the other commands and templates files together.
For example, the declaration file of the lean preset looks like this:
schema_version: "1.0"
preset:
id: "lean"
name: "Lean Workflow"
version: "1.0.0"
description: "Minimal core workflow commands - just the prompt, just the artifact"
author: "github"
repository: "https://github.com/github/spec-kit"
license: "MIT"
requires:
speckit_version: ">=0.6.0"
provides:
templates:
- type: "command"
name: "speckit.specify"
file: "commands/speckit.specify.md"
description: "Lean specify - create spec.md from a feature description"
replaces: "speckit.specify"
- type: "command"
name: "speckit.plan"
file: "commands/speckit.plan.md"
description: "Lean plan - create plan.md from the spec"
replaces: "speckit.plan"
- type: "command"
name: "speckit.tasks"
file: "commands/speckit.tasks.md"
description: "Lean tasks - create tasks.md from plan and spec"
replaces: "speckit.tasks"
- type: "command"
name: "speckit.implement"
file: "commands/speckit.implement.md"
description: "Lean implement - execute tasks from tasks.md"
replaces: "speckit.implement"
- type: "command"
name: "speckit.constitution"
file: "commands/speckit.constitution.md"
description: "Lean constitution - create or update project constitution"
replaces: "speckit.constitution"
tags:
- "lean"
- "minimal"
- "workflow"
- "core"
From this definition, we can see that the purpose of lean is to make the system-provided spec-kit commands more lightweight.
The lean preset is also a special example. It only provides commands, but does not provide templates. The key detail is the type field above.
You can also check other community presets to see how custom template files are declared. I will not expand that part in detail here.
preset demo
After installing lean, its commands will replace the default commands.
Using GitHub Copilot as an example, speckit.specify.agent becomes a simplified version like this:
---
description: Create a specification and store it in spec.md.
---
## User Input
```text
$ARGUMENTS
```
## Outline
1. **Ask the user** for the feature directory path (e.g., `specs/my-feature`). Do not proceed until provided.
2. Create the directory and write `.specify/feature.json`:
```json
{ "feature_directory": "" }
```
3. Create a specification from the user input and store it in `/spec.md`.
- Overview, functional requirements, user scenarios, success criteria
- Every requirement must be testable
- Make informed defaults for unspecified details
Through this example, we can see that preset is not simply extending the workflow from the outside.
Instead, it goes directly into the command and template layer of the core SDD steps. This allows a team to embed its own engineering style, documentation standards, and delivery expectations into the workflow.
Summary
In this article, I shared what I learned about the preset mechanism in spec-kit.
The key idea is:
extension is useful when we want to extend the SDD workflow, while preset is useful when we want to customize the core behavior and output standards inside the SDD workflow.
More specifically:
- Commands define how the coding agent behaves.
- Templates define what the generated documents should look like.
- A
presetcan provide custom commands and templates. - Commands are replaced during preset installation.
- Templates are selected dynamically at runtime based on priority.
For teams that want to make SDD practical in real engineering work, this is a very important capability. It means the team does not need to rely only on verbal conventions or scattered documentation. Instead, the engineering standards can be written directly into the SDD workflow.
That is the real value of spec-kit preset: it turns team engineering standards into executable workflow assets.