| name | Skill Builder |
| description | Guide for creating new skills following best practices. Creates properly formatted SKILL.md files with YAML frontmatter, clear structure, and effective discovery metadata. |
| when_to_use | When user asks to create a new skill, document a technique, capture a workflow, or add instructions for future sessions. When you discover a pattern worth reusing. |
| version | 1.0.0 |
| languages | all |
Skill Builder
Overview
This skill teaches you how to create new skills properly. Skills are reusable instruction sets that extend your capabilities with specialized knowledge, workflows, and best practices.
Core principle: Write skills that future instances of Codex can discover and apply without human intervention.
When to Use This Skill
Use this skill when:
- User asks to "create a skill" or "make a skill"
- You discover a technique that should be reusable
- User wants to document a workflow or pattern
- You're asked to "write this down for next time"
- A process keeps recurring and should be standardized
What Makes a Good Skill
Good skills are:
- ✅ Reusable across multiple projects
- ✅ Clear and actionable (step-by-step)
- ✅ Discoverable (rich metadata)
- ✅ Self-contained (all info needed to use it)
Don't create skills for:
- ❌ One-off solutions
- ❌ Project-specific code (that goes in project docs)
- ❌ Things already well-documented elsewhere
- ❌ Personal preferences without broad applicability
SKILL.md Structure
Every skill must have this structure:
---
name: Human-Readable Skill Name
description: One-line summary of what this does
when_to_use: Detailed triggers, symptoms, and situations when this applies
version: 1.0.0
languages: all | [python, javascript] | specific language
---
# Skill Name
## Overview
2-3 sentence explanation of what this skill does and the core principle.
## When to Use
Bullet list of:
- Specific triggers (error messages, situations)
- Symptoms that indicate you need this
- Types of tasks where this applies
- When NOT to use this
## Core Pattern (if showing before/after)
Brief example showing the wrong way and the right way.
## Quick Reference
Table or bullet list of common operations/commands for quick scanning.
## Implementation
Step-by-step instructions:
1. First step
2. Second step
3. Third step
Include code examples inline when relevant.
## Common Mistakes
What goes wrong + how to fix it:
- ❌ Don't do this
- ✅ Do this instead
## Examples
Real-world concrete examples of using this skill.
The Critical YAML Frontmatter
The YAML section at the top is critical for discovery. Codex finds skills by matching patterns in these fields.
Required Fields
name: - Human-readable title
- Use active voice: "Creating Skills" not "Skill Creation"
- Descriptive: "Time Awareness" not just "Time"
description: - One-line summary
- What does it do in plain language?
- This shows in skill listings
when_to_use: - Discovery metadata (MOST IMPORTANT)
- Be extremely specific
- Include error messages, symptoms, trigger words
- This is how Codex knows to load your skill
- More detail = better discovery
version: - Semantic version (start with 1.0.0)
languages: - Which languages/contexts apply
allfor universal skills[python, javascript]for language-specific[typescript]for single language
Example of Good vs Bad when_to_use
❌ Bad - Too vague:
when_to_use: For git workflows
✅ Good - Specific triggers:
when_to_use: When working on multiple features simultaneously, when you need to preserve work-in-progress, when switching contexts frequently, when you see "detached HEAD" state, or when user mentions "git worktrees"
Step-by-Step Skill Creation Process
Step 1: Identify the Pattern
Ask yourself:
- What technique/pattern did we just use?
- Would this be useful again in a different context?
- Can it be generalized?
- Is it already well-documented elsewhere?
Step 2: Choose a Name
Use this format:
- Action-based: "debugging-with-logs", "creating-tests"
- Pattern-based: "condition-based-waiting"
- Clear and searchable: "git-worktree-workflow"
Avoid:
- Generic names: "helper", "utils"
- Abbreviations: "db-mgmt"
- Unclear references: "the-pattern"
Step 3: Write Discovery Metadata
This is THE MOST IMPORTANT part. Write when_to_use with:
Include specific triggers:
- Error messages: "ENOENT", "Cannot find module"
- Symptoms: "flaky tests", "race conditions"
- Keywords: "async", "parallel", "concurrent"
- User phrases: "how do I...", "keep getting..."
Include context:
- When in the workflow: "before writing code", "when debugging"
- Project types: "React projects", "CLI tools"
- Situations: "when tests are slow", "when merging is difficult"
Step 4: Write Clear Instructions
Use imperative mood:
- ✅ "Run this command"
- ❌ "You should run this command"
Number steps:
- First do this
- Then do this
- Finally do this
Show code examples inline:
# Good examples are commented and complete
git worktree add ../feature-branch feature-branch
Explain WHY, not just WHAT:
## Why condition-based waiting works
Polling with conditions is more reliable than fixed timeouts because...
Step 5: Add Examples
Include 2-3 real-world examples:
- Simple case
- Edge case
- Common variation
Make them concrete - actual code, actual commands, actual scenarios.
Step 6: Document Common Mistakes
Every skill should have this section:
## Common Mistakes
❌ **Mistake:** Description of what goes wrong
✅ **Fix:** How to do it correctly
❌ **Mistake:** Another common error
✅ **Fix:** The right approach
Step 7: Create the File
# Create skill directory (DOTCODEX_DIR defaults to ../dotcodex)
default_dotcodex="${DOTCODEX_DIR:-$(cd .. && pwd)/dotcodex}"
skills_dir="${default_dotcodex}/skills"
mkdir -p "${skills_dir}/skill-name"
# Create SKILL.md file
cat > "${skills_dir}/skill-name/SKILL.md" <<'EOF'
[paste your skill content here]
EOF
# Verify it appears
codex-skills list
# Test loading it
codex-skills use skill-name
Skill Templates by Type
Technique Skill (How-to)
For teaching a specific technique or method.
Focus on:
- Clear step-by-step process
- Code examples
- Before/after comparisons
Example: time-awareness, systematic-debugging
Pattern Skill (Conceptual)
For teaching a way of thinking or mental model.
Focus on:
- The principle/concept
- When to apply it
- Recognition patterns
Example: defensive-programming, separation-of-concerns
Workflow Skill (Process)
For multi-step processes or workflows.
Focus on:
- Ordered steps
- Decision points
- Checkpoints
Example: git-worktree-workflow, code-review-process
Reference Skill (Documentation)
For API docs, command references, syntax guides.
Focus on:
- Quick reference tables
- Command syntax
- Common operations
Example: docker-commands, regex-patterns
Testing Your Skill
After creating a skill, test it:
1. Discovery Test
# Does it show up?
codex-skills list | grep -i "your-skill-name"
2. Loading Test
# Does it load properly?
codex-skills use your-skill-name
3. Format Test
- YAML frontmatter has
---delimiters - All required fields present
- No tabs in YAML (use spaces)
- Headers use
##format - Code blocks use triple backticks
4. Practical Test
- Start a new Codex session
- Create a situation where the skill should apply
- Does Codex discover and use the skill?
- Do the instructions work as expected?
Common Mistakes When Creating Skills
❌ Vague when_to_use
when_to_use: For testing
✅ Better:
when_to_use: When writing unit tests, when tests are flaky, when you see "test timeout" errors, when mocking external dependencies
❌ No concrete examples
Use the command with appropriate flags.
✅ Better:
## Example
```bash
git worktree add ../feature-branch feature-branch
cd ../feature-branch
# Now you can work here independently
### ❌ Missing the "why"
```markdown
Run this command.
✅ Better:
Run this command to avoid race conditions. Fixed timeouts fail when systems are slow; condition-based waiting adapts.
❌ Narrative instead of instructions
Last week we had a bug where...
✅ Better:
## Common Mistakes
When files are locked, you'll see EBUSY errors. Use graceful-fs to retry automatically.
Skill Creation Checklist
When creating a new skill, verify:
Discovery:
-
when_to_useincludes specific trigger words -
when_to_useincludes error messages if applicable -
when_to_useincludes symptoms/situations - Description is clear and specific
- Name is descriptive and searchable
Content:
- Overview explains core principle
- When to Use section is comprehensive
- Instructions are step-by-step and imperative
- Code examples are complete and commented
- Common mistakes section included
- Real-world examples provided
Format:
- YAML frontmatter properly formatted
- All required fields present
- Sections use ## headers
- Code uses triple backtick blocks
- No tabs in YAML (spaces only)
Testing:
- Appears in
codex-skills list - Loads with
codex-skills use skill-name - Actually helps with the intended task
- Can be found when needed
Integration with Workflow
After creating a skill:
- Announce it: Tell the user "I've created a new skill: [name]"
- Explain when to use it: Summarize the triggers
- Offer to test: "Would you like me to test loading this skill?"
- Document it: Keep a project log of custom skills if relevant
Example: Creating a Skill (Full Walkthrough)
User asks: "Can you write down how to handle environment variables properly so we don't forget next time?"
You respond:
"I'll create a skill for environment variable handling. Let me structure this properly..."
default_dotcodex="${DOTCODEX_DIR:-$(cd .. && pwd)/dotcodex}"
skills_dir="${default_dotcodex}/skills"
mkdir -p "${skills_dir}/env-var-handling"
You create:
---
name: Environment Variable Handling
description: Best practices for managing environment variables securely in applications
when_to_use: When setting up new projects, when you see hardcoded secrets, when configuring deployments, when user mentions "env vars" or ".env files", when debugging configuration issues
version: 1.0.0
languages: all
---
# Environment Variable Handling
## Overview
Proper environment variable management keeps secrets out of code, enables configuration across environments, and prevents security vulnerabilities.
## When to Use
- Starting a new project that needs configuration
- See hardcoded API keys or secrets in code
- Deploying to different environments (dev/staging/prod)
- User mentions environment variables or configuration
- Debugging "works on my machine" issues
## Core Pattern
❌ **Wrong:**
```python
API_KEY = "sk-abc123..." # Hardcoded secret
DATABASE_URL = "postgres://localhost"
✅ Right:
import os
API_KEY = os.environ.get('API_KEY')
DATABASE_URL = os.environ.get('DATABASE_URL')
Implementation
- Create .env file for local development:
cat > .env << 'EOF'
API_KEY=your-key-here
DATABASE_URL=postgres://localhost:5432/mydb
NODE_ENV=development
EOF
- Add .env to .gitignore:
echo ".env" >> .gitignore
- Create .env.example template:
cat > .env.example << 'EOF'
API_KEY=your-api-key-here
DATABASE_URL=your-database-url
NODE_ENV=development
EOF
- Load in application:
# Python
from dotenv import load_dotenv
load_dotenv()
// Node.js
require('dotenv').config()
- Access variables:
import os
api_key = os.environ.get('API_KEY')
if not api_key:
raise ValueError("API_KEY not set")
Common Mistakes
❌ Committing .env to git
- Add .env to .gitignore FIRST
- Check with:
git statusbefore committing
❌ No validation
# Bad - fails silently
api_key = os.environ.get('API_KEY')
✅ Validate required vars:
# Good - fails fast with clear error
api_key = os.environ.get('API_KEY')
if not api_key:
raise ValueError("API_KEY environment variable required")
❌ Inconsistent naming
- Use UPPER_SNAKE_CASE consistently
- Not
apiKeyorapi-key
Examples
Example 1: Python Flask app
from flask import Flask
import os
app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
app.config['DATABASE_URI'] = os.environ.get('DATABASE_URL')
if not app.config['SECRET_KEY']:
raise ValueError("SECRET_KEY must be set")
Example 2: Node.js Express app
require('dotenv').config()
const app = express()
const PORT = process.env.PORT || 3000
const DB_URL = process.env.DATABASE_URL
if (!DB_URL) {
throw new Error('DATABASE_URL must be set')
}
Production Deployment
For production:
- Set env vars in hosting platform (Heroku, AWS, etc.)
- Never commit production secrets
- Use secret management tools for sensitive data
- Rotate secrets regularly
Remember: If it's a secret or configuration, it belongs in an environment variable, not in code.
**You save it:**
```bash
# Save the skill
cat > "${skills_dir}/env-var-handling/SKILL.md" <<'EOF'
[content above]
EOF
You verify:
codex-skills list
# Should show: Environment Variable Handling
You announce:
"I've created the 'env-var-handling' skill. It will activate whenever you mention environment variables, configuration, or when I see hardcoded secrets. You can load it anytime with codex-skills use env-var-handling."
Advanced: Skill Families
Related skills can reference each other:
## Related Skills
See also:
- `codex-skills use security-best-practices` for broader security patterns
- `codex-skills use docker-config` for containerized deployments
This creates a knowledge graph of interconnected skills.
Meta-Skill: Using This Skill
When user asks you to create a skill:
- Announce: "I'll create a new skill for [topic]"
- Ask clarifying questions if needed:
- What should trigger this skill?
- What are common error messages?
- What mistakes should we warn about?
- Follow this skill's structure
- Create the file in
${DOTCODEX_DIR:-../dotcodex}/skills/(symlinked to~/.codex/skills/) - Verify with
codex-skills list - Announce completion and when it will activate
Remember: You're creating instructions for your future self. Be clear, be specific, be helpful.
This skill is itself an example of a well-structured skill. Use it as a template!