Lesson 4
Skills
What Skills Are
A skill is a modular instruction package that teaches Kiro how to do something specific. Unlike steering (which provides persistent background knowledge), a skill is a complete set of instructions for a particular task or workflow - activated on demand.
You're using one right now: the teach skill that drives this entire learning experience.
Skills vs Steering vs Hooks
| Feature | Purpose | When loaded |
|---|---|---|
| Steering | Background knowledge and rules | Always, on file match, or manually |
| Skills | Complete workflow instructions | When activated by keyword or slash command |
| Hooks | Automated event-driven actions | When a specific event fires |
The key distinction: steering tells Kiro what to remember, skills tell Kiro how to do a task end-to-end, and hooks tell Kiro what to do automatically when something happens.
Where Skills Come From
When you type / in the chat input, you'll see skills from three sources mixed together:
| Source | Location | Example |
|---|---|---|
| Built-in | Bundled with Kiro (not editable) | /quick-spec, /architecture-selection |
| Global | ~/.kiro/skills/*.md | Your personal cross-project skills |
| Workspace | .kiro/skills/*.md | Project-specific team skills |
There's no visual separator in the menu indicating which source a skill comes from - they're all listed together. Built-in skills work exactly like user-created ones (same activation, same invocation) but you can't edit them.
Where Skills Live (Your Skills)
Same two-scope pattern as steering:
| Scope | Location | Use for |
|---|---|---|
| Workspace | .kiro/skills/*.md | Project-specific workflows (team deployment, code review process) |
| Global (User) | ~/.kiro/skills/*.md | Personal workflows you use across all projects (your PR style, documentation process) |
Like steering, only .md files directly in the folder are documented as being picked up - subdirectory support is not mentioned in official docs.
The Skill File Format
A skill is a single .md file with YAML front-matter followed by markdown instructions:
---
name: deploy
description: Deploy the application to staging or production environments
argument-hint: "Which environment? (staging/production)"
---
## Deployment Process
When asked to deploy, follow these steps:
1. Run the test suite: `npm test`
2. Build the application: `npm run build`
3. Check which environment the user wants...
...
Front-matter Schema (Complete)
| Key | Required | What it does |
|---|---|---|
name | Yes | The skill's identifier. Becomes the slash command name (e.g. /deploy) |
description | Yes | Used for auto-activation - Kiro matches your prompt against this text to decide if the skill is relevant |
argument-hint | No | Purely cosmetic - a UI hint suggesting what input to provide when invoking the skill. Does not affect activation, behaviour, or what gets passed to the model. The only functional keys are name and description. |
That's the complete schema. Three keys - one optional.
How Skills Are Activated
There are two activation paths:
1. Automatic activation (keyword matching)
Kiro reads the description field of all available skills. When your prompt matches a skill's description semantically, Kiro loads the full skill content automatically.
For example, if a skill has description: "Deploy the application to staging or production" and you type "deploy the app to staging", Kiro will activate that skill.
name and description are loaded at startup. The full skill content (the markdown body) is loaded on demand when activated. This means skills don't cost context tokens until they're needed - unlike always-on steering. The metadata does use tokens (maybe 10 - 30 per skill), but that's negligible - 20 skills might cost ~500 tokens of metadata overhead total, compared to potentially thousands for the full body of a single skill. The expensive part stays out until needed.
2. Explicit invocation
Type / in the chat input and you'll see your skills listed as slash commands. Select one to load its full instructions. You can also find skills via # in the context menu alongside files and steering.
/ slash menu shows both built-in and user-created skills as slash commands - this is the primary way to explicitly invoke a skill. Skills also appear in the # context menu. Both work the same way: the skill's full instructions are loaded into context for that message.
What Makes a Good Skill
A skill should be:
- Self-contained - all the instructions needed to complete the task, from start to finish
- Task-oriented - focused on a specific workflow, not general knowledge
- Detailed - unlike steering (which should be concise), skills can be long because they only load when needed
The teach skill you're using is ~150 lines of detailed instructions covering philosophy, methodology, file formats, and workflow. That's fine for a skill - it only loads when teaching is requested. You'd never put that much in a steering file.
File References in Skills
Skills support the same #[[file:...]] syntax as steering:
---
name: api-review
description: Review API endpoint code for correctness and standards compliance
---
## API Review Process
Check the code against our API standards defined in #[[file:docs/api-standards.md]]
and ensure all endpoints match the schema in #[[file:docs/openapi.yaml]]
...
Referenced files are loaded alongside the skill when it activates. The same rules apply as with steering: the referenced files are just content embeds with no independent inclusion logic.
Skills Can Be Large
Since skills only load on demand, they can afford to be comprehensive. Good use cases for skills:
- Complex workflows - multi-step deployment, database migration, release process
- Teaching/coaching - the teach skill in this workspace
- Code generation templates - "create a new API endpoint following our patterns"
- Review checklists - PR review, security audit, accessibility review
- Onboarding guides - "explain this codebase to a new developer"
A Real Example: Commit Message Skill
Something you might currently do by typing instructions in chat every time - generate a commit message from the current diff in a specific format. As a skill, the instructions are codified and reusable:
---
name: commit-message
description: Generate a git commit message from the current staged or unstaged changes
argument-hint: "Any additional context about the change?"
---
## Commit Message Generation
When asked to generate a commit message:
1. Get the current branch name: `git rev-parse --abbrev-ref HEAD`
2. Get the diff since last commit: `git diff` (or `git diff --cached` if changes are staged)
3. Analyse the changes — which files changed, what was the intent
## Format
Generate the commit message in this format:
```
[branch-name] Short title (max 72 chars)
- What changed (files/areas affected)
- Why it changed (intent, not just "updated X")
- Any notable decisions or trade-offs
```
## Rules
- Title should be imperative mood ("Add feature" not "Added feature")
- Keep the title under 72 characters
- The body should explain *why*, not just *what* — the diff shows what
- Group related file changes together in the description
This auto-activates when you say "generate a commit message" or "commit message", or you invoke it explicitly with /commit-message. No more re-typing your format preferences every time.
A Real Example: PR Review Skill
---
name: pr-review
description: Review a pull request for code quality, security, and standards compliance
argument-hint: "Which PR or branch to review?"
---
## Pull Request Review
When reviewing a PR, follow this process:
### 1. Understand the change
- Read the PR description or commit messages
- Identify which files changed and why
### 2. Check for correctness
- Does the code do what it claims?
- Are edge cases handled?
- Are there off-by-one errors, null checks, race conditions?
### 3. Check standards
- Follows our naming conventions (see #[[file:docs/naming.md]])
- Uses approved libraries (no new dependencies without discussion)
- Has appropriate test coverage
### 4. Check security
- No secrets or credentials in code
- Input validation on all external data
- SQL queries use parameterised statements
### 5. Provide feedback
- Be specific: reference file and line
- Suggest fixes, don't just point out problems
- Separate blocking issues from nits
Skills vs Steering: Full Comparison
Skills and steering share a lot of surface-level traits. Here's what's identical and what diverges:
What's identical
- Both are markdown files with YAML front-matter
- Both live in
.kiro/subfolders (steering/andskills/) - Both have workspace and global scopes (
.kiro/and~/.kiro/) - Both support
#[[file:...]]references - Both can be invoked via
/slash commands and#context keys - Both inject text into the model's context when loaded
What's different
| Steering | Skills | |
|---|---|---|
| Purpose | Background knowledge - rules, conventions, context | Task instructions - how to do a specific thing end-to-end |
| Front-matter | inclusion, fileMatchPattern (2 keys) | name, description, argument-hint (3 keys) |
| Can auto-load | Yes (inclusion: auto, fileMatch) | Yes (keyword match against description) |
| Auto-load trigger | Always, or when a matching file enters context | When your prompt semantically matches the description |
| Ideal length | Short (every token costs on every message if always-on) | Can be long (only loads on demand, zero cost until activated) |
| Startup cost | Always-on files fully loaded at startup | Only name + description loaded (body loads later) |
| Posture | Passive - "here's what to know" | Active - "here's what to do" |
| Conditional on file type | Yes (fileMatch) | No - keyword-based only |
The grey area: manual steering vs skills
This is where the overlap is most confusing. A manual steering file and a skill are both loaded only when invoked, both available via / and #, and both are markdown with front-matter. Mechanically, Kiro treats them the same way - the difference is in how you write the content and your intent:
- Manual steering = reference material you want Kiro to be aware of ("here are our API conventions")
- Skill = a procedure you want Kiro to follow ("here's how to do a code review step by step")
If you're unsure which to use: if the content is mostly declarative (rules, standards, schemas) → steering. If it's mostly imperative (steps, decisions, workflows) → skill.
Your Tangible Win
You can now create skills for any workflow your team repeats. You know the full front-matter schema (three keys), both activation paths (auto and slash), how file references work, and when to choose skills over steering. You also understand why skills are ideal for large instruction sets - they're free until activated.