Claude Code custom skills ile tekrarlayan işleri otomatikleştirin
Her projede aynı şeyleri tekrar tekrar yazıyorum: yeni bir API endpoint oluştururken route dosyası, validation şeması, test dosyası, tür tanımları. Claude Code'a her seferinde aynı prompt'u vermek yerine bu akışı bir kere tanımlayıp tekrar kullanmak istiyordum. Custom skills tam olarak bu sorunu çözüyor.
SKILL.md nedir ve nereye konur?
Claude Code, çalışma dizininde .claude/skills/ klasörü altındaki Markdown dosyalarını otomatik olarak bağlam (context) olarak kullanır. Her .md dosyası bir "skill" tanımı. İçinde doğal dilde yazılmış talimatlar, kod şablonları ve kurallar bulunur.
Dizin yapısı şöyle görünür:
.claude/
├── settings.json
└── skills/
├── new-api-route.md
├── component-scaffold.md
└── db-migration.mdBu dosyalar projeye commit'lenir. Ekipteki herkes aynı skill'leri kullanır, Claude Code bunları otomatik keşfeder.
İlk skill dosyasını yazmak
Bir Next.js projesinde yeni bir API route oluşturma akışını düşünelim. Her seferinde route handler, Zod şeması, hata yönetimi ve test dosyası gerekiyor. Bunu new-api-route.md olarak tanımlıyorum:
# Yeni API route oluşturma
Bu skill, App Router altında yeni bir API route oluşturur.
## Kurallar
- Route dosyası `app/api/[route-name]/route.ts` altına konur
- Her route için Zod validation şeması `lib/validations/` altında ayrı dosyada tutulur
- Hata dönerken NextResponse.json kullanılır, status code açıkça belirtilir
- Her route için `__tests__/api/` altında test dosyası oluşturulur
## Şablon: Route handler
```typescript
import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const validated = schema.parse(body);
// iş mantığı
return NextResponse.json({ data: result }, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ error: error.flatten().fieldErrors },
{ status: 400 }
);
}
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}Şablon: Test dosyası
Vitest kullanılır. Route handler doğrudan import edilip test edilir.
Bu dosya `.claude/skills/new-api-route.md` olarak kaydedildiğinde, Claude Code'a "yeni bir API route oluştur" dediğimde bu şablonu ve kuralları takip ediyor.
## Custom slash commands ile skill'leri tetiklemek
Skill dosyaları pasif bağlam sağlar; Claude Code onları gerektiğinde okur. Ama bazen doğrudan bir komutla tetiklemek daha pratik. Custom slash commands bunun için var.
`.claude/commands/` dizini altına Markdown dosyaları koyarak kendi slash command'larınızı tanımlarsınız:
.claude/ ├── commands/ │ ├── new-route.md │ └── add-component.md └── skills/ └── ...
`new-route.md` dosyasının içeriği:
```markdown
Kullanıcının belirttiği isimle yeni bir API route oluştur.
1. `.claude/skills/new-api-route.md` dosyasındaki kurallara ve şablona uy
2. Route adını parametre olarak al: $ARGUMENTS
3. Şu dosyaları oluştur:
- app/api/$ARGUMENTS/route.ts
- lib/validations/$ARGUMENTS.ts
- __tests__/api/$ARGUMENTS.test.ts
4. Oluşturduğun dosyaları listele$ARGUMENTS yer tutucusu, komut çağrılırken verilen argümanları temsil eder. Claude Code içinde şöyle kullanılır:
/new-route usersBu komut çalıştığında Claude Code, skill dosyasındaki şablonları okur ve üç dosyayı birlikte oluşturur.
Kişisel ve proje düzeyinde ayrım
İki farklı yerden command tanımlanabiliyor:
Proje düzeyinde: .claude/commands/ dizini. Repo'ya commit'lenir, ekip genelinde geçerli.
Kişisel düzeyde: ~/.claude/commands/ dizini (home klasörü altında). Sadece o kullanıcının tüm projelerinde çalışır, repo'ya girmez.
Ben kişisel düzeyde genel amaçlı command'lar tutuyorum. Mesela bir review.md:
Son git diff'i incele ve şu başlıklar altında değerlendir:
1. Tür güvenliği: any kullanımı var mı, tip daraltma eksik mi?
2. Hata yönetimi: catch blokları error tipini kontrol ediyor mu?
3. Test kapsamı: değişen fonksiyonlar için test var mı?
Sorunları bulduktan sonra düzeltme önerileri sun./review dediğimde hangi projede olursam olayım bu akış çalışır.
Skill dosyasında ne yazılmalı, ne yazılmamalı
Skill dosyalarını yazarken birkaç şeyi deneyerek öğrendim.
İşe yarayan yaklaşım: somut kurallar ve kod şablonları koymak. "Dosya şuraya konur, şu pattern kullanılır, hata şöyle handle edilir" gibi net talimatlar Claude Code'un tutarlı çıktı üretmesini sağlıyor.
İşe yaramayan yaklaşım: çok soyut veya çok uzun talimatlar. "Clean code prensiplerine uy" gibi ifadeler pratikte hiçbir şeyi değiştirmiyor. Skill dosyası 200 satırı geçtiğinde de Claude Code'un ilgili kısmı bulması zorlaşıyor.
Bir skill dosyası tek bir iş akışına odaklanmalı. "Genel kodlama kuralları" diye bir skill yazmak yerine bu tür kuralları .claude/settings.json veya CLAUDE.md dosyasına koymak daha doğru. Skill, tekrar eden belirli bir görevi tanımlar.
Gerçek bir örnek: React bileşen iskelesi
Projemde her yeni bileşen için dört dosya oluşturuyorum: bileşen dosyası, tür dosyası, test dosyası, Storybook dosyası. Bu akışı component-scaffold.md skill'i olarak tanımladım:
# React bileşen iskelesi
## Dosya yapısı
Bileşen adı PascalCase olarak verilir. Dosyalar şu yapıda oluşturulur:
components/ └── [ComponentName]/ ├── index.ts (re-export) ├── [ComponentName].tsx ├── [ComponentName].types.ts └── [ComponentName].test.tsx
## Bileşen dosyası kuralları
- Props interface'i ayrı .types.ts dosyasında tanımlanır
- Default export kullanılmaz, named export tercih edilir
- forwardRef gerekiyorsa React.forwardRef kullanılır
- className prop'u her zaman kabul edilir, cn() utility ile birleştirilir
## Şablon: Bileşen
```tsx
import { cn } from "@/lib/utils";
import type { ComponentNameProps } from "./ComponentName.types";
export function ComponentName({ className, ...props }: ComponentNameProps) {
return (
<div className={cn("base-class", className)} {...props}>
{/* içerik */}
</div>
);
}Şablon: Types
import type { ComponentPropsWithoutRef } from "react";
export interface ComponentNameProps extends ComponentPropsWithoutRef<"div"> {
// bileşene özgü prop'lar
}
Bunu `/add-component Button` şeklinde çağırıyorum. Dört dosya birlikte oluşuyor, isimlendirme ve yapı her seferinde tutarlı kalıyor.
## Skill'leri ekip içinde paylaşmak
`.claude/skills/` ve `.claude/commands/` dizinleri repo'nun parçası olduğu için PR ile paylaşılır. Birisi yeni bir skill eklediğinde veya mevcut olanı güncellediğinde, code review sürecinden geçer.
Birkaç pratik not:
Skill dosyalarının üstüne kısa bir yorum satırı eklemek faydalı: ne zaman oluşturuldu, kim yazdı, hangi sorunu çözüyor. Claude Code bu bilgiyi kullanmaz ama ekip üyeleri dosyayı açtığında bağlamı hızlıca anlar.
Skill dosyalarını `CLAUDE.md` dosyasında referans verebilirsiniz. Projenin kök dizinindeki `CLAUDE.md` genel kuralları içerir; skill dosyaları ise belirli akışları tanımlar. İkisi birbirini tamamlar.
```markdown
# CLAUDE.md
## Proje kuralları
- TypeScript strict mode kullanılır
- Biome formatter ve linter aktif
## Mevcut skill'ler
- `new-api-route`: Yeni API endpoint oluşturma akışı
- `component-scaffold`: React bileşen iskelesi
- `db-migration`: Drizzle ORM migration oluşturmaSkill'leri veritabanı migration'ları için kullanmak
Drizzle ORM kullanan bir projede migration akışı da tekrarlayan bir iş. Yeni bir tablo eklerken şema dosyası, migration komutu ve seed verisi oluşturmak gerekiyor. Bunu da bir skill olarak tanımlıyorum:
# Drizzle migration oluşturma
## Adımlar
1. Şema dosyasını `db/schema/` altında oluştur
2. Tablo tanımında `createdAt` ve `updatedAt` alanları her zaman ekle
3. `npx drizzle-kit generate` komutunu çalıştır
4. Oluşan migration dosyasını kontrol et
## Şema kuralları
- Tablo isimleri snake_case ve çoğul olur
- Primary key her zaman `id` adında serial/uuid olur
- Foreign key alanları ilişkili tablo adının tekil hali + `Id` şeklinde isimlendirilirMCP sunucuları ile birlikte kullanım
Skill dosyaları, MCP sunucuları ile birlikte çalışabilir. Mesela bir skill dosyasında "veritabanı şemasını kontrol etmek için MCP aracını kullan" diye talimat verebilirsiniz. Claude Code, MCP tool'unu çağırır ve skill'deki kurallara göre sonucu işler.
Bu kombinasyon özellikle dış servislerle etkileşim gerektiren akışlarda işe yarar: veritabanı durumunu sorgula, API dokümantasyonunu çek, CI sonuçlarını kontrol et.
Ne zaman skill yazmalı, ne zaman yazmamalı
Skill yazmak bir yatırım. Her küçük iş için skill dosyası oluşturmak, bakım yükü getirir. Benim kuralım basit: aynı akışı üçüncü kez tekrarladığımda skill dosyasına dönüştürüyorum. İki kez yaptıysam belki tesadüftür, üç kez yaptıysam bir pattern var demektir.
Skill dosyası yazmanın karşılığını vermediği durumlar da var. Tek seferlik, projeye özgü görevler için skill oluşturmak gereksiz. Aynı şekilde, çok sık değişen akışlar için de skill dosyası hızla eskir. Skill, belirli bir olgunluğa ulaşmış, kararlı akışlar için en iyi sonucu verir.
Bir de şunu fark ettim: iyi yazılmış bir skill dosyası aynı zamanda bir dokümantasyon görevi görür. Ekibe yeni katılan birisi .claude/skills/ dizinine bakarak projenin tekrar eden akışlarını, dosya yapısı konvansiyonlarını ve kodlama kalıplarını birkaç dakikada anlayabiliyor. Claude Code'dan bağımsız olarak bile değeri var.