← Back to posts

How I Build Custom Skills for Claude Code (And Why You Should Too)

The thought process behind creating reusable skills that turned repetitive dev workflows into one-command automations — from Jira-to-PR pipelines to automated verification.

AIClaude CodeAutomationDeveloper ExperienceProductivity

In my last post, I shared my Claude Code workflows after 280+ messages. One thing kept coming up in conversations after that: people wanted to know more about the custom skills I built. Not just what they do, but how I think about creating them.

So here's the breakdown. Not a tutorial on skill syntax — you can find that in the docs. This is about the thought process: identifying what to automate, designing the skill, iterating on it, and the mistakes I made along the way.

What Made Me Start Building Skills

I didn't set out to build skills. I set out to stop repeating myself.

After a couple of weeks using Claude Code daily, I noticed a pattern in my sessions. Every time I picked up a bug ticket, I'd go through the same sequence: fetch the Jira ticket, read the description, create a branch with a specific naming convention, implement the fix, run the build, test it, commit, push, create the PR, and transition the ticket. Every. Single. Time.

The individual steps weren't hard. But the cognitive overhead of orchestrating them — making sure I followed the right branching strategy, remembered to include the ticket number in the PR title, linked the Jira ticket correctly — was real. And when Claude forgot a step mid-flow, I'd have to re-explain the whole process.

That's when I realized: if I'm giving Claude the same multi-step instructions repeatedly, I should encode those instructions once and reuse them.

Skill #1: The Jira-to-PR Pipeline

This was my first real skill, and it went through three distinct iterations before it became useful.

Version 1: The Naive Approach

My first attempt was basically a copy-paste of the prompts I'd been giving Claude manually:

# Bugfix Workflow
1. Fetch the Jira ticket
2. Create a bugfix branch
3. Implement the fix
4. Create a PR

This was... not great. It was too vague. Claude would create branches with inconsistent naming, forget to include the ticket ID in commit messages, and sometimes skip the build step entirely. The skill captured what to do but not how to do it — and the "how" is where all the value lives.

Version 2: Encoding the Conventions

The breakthrough came when I started encoding my team's actual conventions into the skill. Instead of "create a branch," I specified the exact naming pattern. Instead of "create a PR," I described what the PR title and description should contain:

# Bugfix Workflow

## Branch Strategy
- Branch name format: `bugfix/TICKET-ID-short-description`
- Always branch from the latest `develop`

## Implementation
- Fetch the Jira ticket using JQL: `key = TICKET-ID`
- Read the ticket description and acceptance criteria
- Implement the fix across all affected files
- Run `npm run build` after every change — do not skip this

## PR Creation
- PR title: `[TICKET-ID] Short description of the fix`
- PR description must include:
  - What was broken
  - What was changed
  - How it was tested
- Transition the Jira ticket to "In Review"

This was significantly better. But I still hit friction.

Version 3: Handling the Edge Cases

The final version came from accumulating failure patterns. Every time a session went sideways, I'd ask myself: "Could the skill have prevented this?" Usually the answer was yes.

The biggest improvements came from encoding workarounds for tool quirks. For example, the Jira MCP integration occasionally returns empty results on the first call. Instead of Claude stalling and retrying the same failing approach, I added fallback logic directly into the skill:

## Fetching the Ticket
- First try: use the Jira MCP tool with the ticket key
- If the response is empty: fall back to JQL search `key = TICKET-ID`
- If both fail: ask the user for the ticket details manually

I also learned to be explicit about what "done" means. Without a clear completion criteria, Claude would sometimes declare victory after editing the code but before verifying the build passed:

## Definition of Done
A bugfix is NOT complete until:
1. The build passes with zero errors
2. The fix has been verified (visually or via tests)
3. The PR has been created and linked to the Jira ticket
4. The Jira ticket has been transitioned

Why Three Skills Instead of One

Eventually I split the single skill into three: hotfix, bugfix, and feature. They share the same structure but differ in branching strategy, the base branch they start from, and how aggressive the testing requirements are. A hotfix branches from main and has stricter verification requirements. A feature branch might involve more exploratory work.

This separation might seem like overkill, but it eliminated a whole class of errors where Claude would use the wrong branching strategy because the context was ambiguous. When I type /bugfix, Claude knows exactly which conventions apply. No guessing.

Skill #2: The Verification Workflow

This one was born from pain. If you read my previous post, you know that one of my biggest friction points was Claude skipping testing until I explicitly asked. The data from my usage report backed this up — multiple sessions where the fix was technically correct but broke something else because nobody verified it.

The verification skill is simpler than the Jira pipeline but arguably more impactful:

# Verify Changes

After implementing any code change, run this verification sequence:

## Step 1: Build Check
- Run `npm run build`
- If there are TypeScript errors, fix them before proceeding
- Do NOT skip this step

## Step 2: Browser Verification
- Use Playwright to navigate to the affected page
- Take a snapshot and confirm the UI renders correctly
- Check the browser console for runtime errors or failed requests

## Step 3: Targeted Testing
- Interact with the specific feature that was changed
- Click buttons, submit forms, verify data displays correctly
- If anything fails, fix it and re-verify

## Step 4: Report
- Build status: pass/fail
- Visual verification: what the page looks like
- Console status: any errors or warnings
- Overall: ready to ship or needs more work

The key insight here was that this skill doesn't need to be invoked manually every time. I reference it from my other skills. The bugfix skill's "Definition of Done" includes running the verification steps. This creates a chain: /bugfix triggers the implementation, which triggers verification, which triggers the PR only if everything passes.

The Thought Process: How I Decide What Becomes a Skill

Not everything should be a skill. I've learned to apply a simple filter:

Make it a skill when: the workflow has more than three steps, you've done it at least three times, and the steps involve conventions that Claude wouldn't know without being told. If all three are true, it's worth the 15 minutes to write the skill.

Don't make it a skill when: the task is genuinely different each time, or when the value is in the thinking rather than the execution. Architecture decisions, for example — those require context that changes every time. I don't want Claude running on autopilot for those.

There's also a middle ground I use heavily: rules in CLAUDE.md. These are conventions that apply across all workflows rather than being specific to one. Things like "always check the API response structure before assuming a bug is frontend" or "when debugging, add logs before guessing." These aren't skills — they're guardrails that make every session better.

What I Got Wrong (And What I'd Do Differently)

I over-specified at first. My early skills tried to anticipate every possible scenario. They were long, and Claude would sometimes get confused by the branching logic. Shorter, more focused skills work better. Let Claude figure out the details — just give it the constraints and conventions it needs to stay on track.

I didn't test the skills themselves. This sounds obvious in retrospect, but the first few times I used a new skill, I didn't verify that Claude actually followed all the steps. I'd just trust the output. Now I treat the first three uses of any new skill as a testing phase. I watch closely, note where Claude deviates, and refine the instructions.

I waited too long to split skills apart. The monolithic "do everything" skill was harder to maintain and harder for Claude to follow than three focused ones. If your skill has conditional logic ("if hotfix, do X; if feature, do Y"), that's a sign it should be multiple skills.

The Compound Effect

The real payoff isn't any single skill — it's how they compound. When I sit down to work on a bug, my workflow looks like this:

  1. /bugfix TICKET-123 — Claude fetches the ticket, creates the branch, implements the fix, verifies it, and opens the PR
  2. I review the PR diff and the Playwright verification screenshots
  3. If something's off, I give Claude a one-line correction and it re-runs the verification

What used to be a 30-minute sequence of context switching — between Jira, the terminal, the browser, the code editor, and GitHub — is now a single command followed by a review. The cognitive load dropped dramatically.

And because the skills encode my team's conventions, the output is consistent. Every PR follows the same format. Every branch uses the right naming pattern. Every fix gets verified before the PR is created. That consistency is worth more than the time savings.

Getting Started

If you want to build your own skills, here's what I'd suggest:

Start by tracking your friction for a week. Every time you repeat instructions to Claude, write them down. After a few days, you'll see patterns. The most repeated instructions are your first skills.

Keep the first version simple. Three to five steps. Focus on the conventions Claude wouldn't know — branching patterns, naming conventions, testing expectations. You can always add more later.

Build in verification. Whatever the skill does, include a step that confirms it worked. A build check, a screenshot, a test run — something. This single addition prevents more wasted sessions than anything else.

And iterate. Skills are code for Claude. They deserve the same treatment: start simple, test them, refine based on real usage, and don't be afraid to refactor when they get unwieldy.

The goal isn't to automate yourself out of the loop. It's to automate the parts that don't need your brain, so you can focus on the parts that do.