Menyiapkan Husky + lint-staged dengan Claude Code: panduan pre-commit praktis
Gunakan Claude Code, Husky, dan lint-staged untuk menjalankan ESLint serta Prettier sebelum commit.
Claude Code bisa mengubah banyak file dalam satu sesi. Itu sangat membantu saat refactor, menambah test, atau merapikan konfigurasi, tetapi juga membuat review lebih berisik. Reviewer seharusnya fokus pada perilaku aplikasi, desain API, dan risiko perubahan, bukan mengejar import yang tidak dipakai atau format Markdown yang bergeser.
Husky + lint-staged memberi pagar kualitas yang sederhana. Git hook adalah script kecil yang dijalankan Git pada titik tertentu, misalnya sebelum commit dibuat. Husky membuat hook itu mudah disimpan di repository dan dipakai bersama tim. lint-staged menjalankan command hanya pada file yang sudah masuk staging dengan git add, sehingga tidak perlu memeriksa seluruh project setiap kali commit. Claude Code hooks berbeda: hook itu berjalan di lifecycle Claude Code. Ia berguna sebagai bantuan, tetapi tidak menggantikan Git hook yang berlaku untuk semua commit.
Tujuan artikel ini bukan membuat CI lokal yang berat. Pola yang lebih sehat adalah: pre-commit untuk pemeriksaan cepat, pre-push untuk pemeriksaan project, dan CI untuk validasi penuh.
Alur Kerja
Pembagian paling stabil adalah menjaga pre-commit tetap ringan. Format dan lint bisa berjalan sebelum commit; typecheck, test, dan build sebaiknya pindah ke pre-push atau CI. Dengan begitu tim tidak tergoda memakai --no-verify hanya karena hook terlalu lambat.
flowchart LR
A["Claude Code mengedit file"] --> B["Developer memilih file dengan git add"]
B --> C["Husky pre-commit"]
C --> D["lint-staged"]
D --> E["ESLint / Prettier"]
E --> F["commit"]
C --> G["typecheck, test, build di pre-push atau CI"]
Saya memakai referensi resmi terbaru: Husky Get started, lint-staged README, manual Git hooks, dan Claude Code hooks reference. Detail pentingnya: Husky menggunakan npx husky init untuk setup awal, dan lint-staged membutuhkan hook pre-commit plus konfigurasi pattern file.
Setup Minimal yang Berjalan
Jika ESLint atau Prettier belum stabil, rapikan dulu dengan panduan ESLint Claude Code dan panduan Prettier. Husky hanya memanggil command; kualitas akhirnya tetap bergantung pada command tersebut.
Prompt untuk Claude Code sebaiknya spesifik:
Tambahkan Husky dan lint-staged ke repository Node.js/TypeScript ini.
pre-commit hanya boleh memproses file JS, TS, JSON, Markdown, dan CSS yang staged.
Jalankan ESLint auto-fix dan Prettier di pre-commit.
Jangan taruh typecheck, test, atau build di pre-commit; pindahkan ke pre-push atau CI.
Setelah selesai, tulis command manual untuk verifikasi.
Instalasi manualnya singkat:
npm install --save-dev husky lint-staged eslint prettier
npx husky init
npx husky init membuat .husky/pre-commit dan memperbarui script prepare di package.json. Ganti isi hook yang dibuat menjadi:
#!/usr/bin/env sh
npx lint-staged
Tambahkan konfigurasi ini ke package.json. Jika sudah ada scripts, merge key yang diperlukan dan jangan menimpa semuanya.
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix --max-warnings=0",
"prettier --write"
],
"*.{json,md,mdx,yml,yaml,css,scss}": [
"prettier --write"
]
}
}
Uji dengan file yang sengaja dibuat berantakan:
git add src/example.ts
npx lint-staged --debug
git commit -m "chore: verify pre-commit checks"
Mode --debug menampilkan konfigurasi yang dipakai, file yang cocok dengan glob, dan command yang dijalankan. Saat hook gagal, kirim output ini ke Claude Code agar diagnosisnya berbasis data.
Konfigurasi yang Mudah Dirawat
Untuk repository yang mulai besar, saya lebih suka memindahkan konfigurasi ke lint-staged.config.mjs. package.json tetap ringkas, dan kita bisa menulis helper kecil. Contoh berikut memberi quote pada nama file supaya path dengan spasi tidak mudah gagal.
// lint-staged.config.mjs
const shellQuote = (file) => `"${file.replaceAll('"', '\\"')}"`;
const joinFiles = (files) => files.map(shellQuote).join(" ");
export default {
"*.{js,jsx,ts,tsx}": (files) => [
`eslint --fix --max-warnings=0 ${joinFiles(files)}`,
`prettier --write ${joinFiles(files)}`,
],
"*.{json,md,mdx,yml,yaml,css,scss}": (files) =>
`prettier --write ${joinFiles(files)}`,
};
Setelah memakai file ini, hapus key lint-staged dari package.json. Dua sumber konfigurasi akan membingungkan tim dan membuat edit dari Claude Code kurang dapat diprediksi.
Tiga Use Case
Use case pertama adalah aplikasi TypeScript. Claude Code sering mengubah komponen, test, dan utility sekaligus. ESLint auto-fix dan Prettier mengurangi noise sebelum review. Typecheck penuh lebih cocok di pre-push atau CI karena membutuhkan konteks project dan bisa memakan waktu.
Use case kedua adalah situs Astro atau Next.js berbasis konten. MDX, JSON metadata, CSS, dan TypeScript sering berubah bersama. lint-staged menjaga diff artikel tetap bersih, sehingga reviewer bisa membaca konten, bukan memeriksa spasi.
Use case ketiga adalah monorepo. Menjalankan semua test semua package di pre-commit hampir selalu terlalu lambat. Jalankan format dan lint pada file staged, lalu biarkan CI atau task runner memilih test package berdasarkan path yang berubah.
commit-msg dan pre-push
Aturan commit message sebaiknya dipisah ke hook commit-msg. Untuk Conventional Commits, commitlint adalah pilihan umum.
npm install --save-dev @commitlint/cli @commitlint/config-conventional
// commitlint.config.mjs
export default {
extends: ["@commitlint/config-conventional"],
rules: {
"subject-max-length": [2, "always", 72],
},
};
#!/usr/bin/env sh
npx --no -- commitlint --edit "$1"
Letakkan shell di atas dalam .husky/commit-msg. Untuk pemeriksaan yang lebih berat, gunakan .husky/pre-push:
#!/usr/bin/env sh
npm run validate
Script validate bisa disamakan dengan CI:
{
"scripts": {
"typecheck": "tsc --noEmit",
"test:ci": "vitest run --coverage",
"build": "vite build",
"validate": "npm run typecheck && npm run lint && npm run format:check && npm run test:ci && npm run build"
}
}
Jebakan Umum
Jebakan terbesar adalah membuat pre-commit terlalu berat. Jika setiap commit butuh dua menit, tim akan belajar melewati hook. Jika hanya beberapa detik, hook menjadi kebiasaan.
Jebakan kedua adalah partial staging. lint-staged bekerja pada file staged, tetapi file yang sama bisa memiliki perubahan unstaged. Saat hasilnya membingungkan, lihat git status --short, git diff --staged, dan npx lint-staged --debug bersama-sama.
Untuk tim campuran Windows, macOS, dan Linux, line ending juga penting. Hook Husky adalah shell script, jadi LF adalah pilihan paling aman.
* text=auto eol=lf
*.cmd text eol=crlf
*.bat text eol=crlf
Hindari juga solusi seperti || true. Itu menyembunyikan kegagalan dan membuat quality gate tidak berguna. Lebih baik pendekkan pesan error, pindahkan tugas lambat ke pre-push, atau dokumentasikan command perbaikannya.
Hasil yang Saya Coba
Saya mencoba struktur ini pada project TypeScript/Vite kecil dengan format yang sengaja dirusak, import tidak terpakai, dan masalah spasi MDX. pre-commit tetap cepat karena hanya memproses file staged. npx lint-staged --debug memperlihatkan file dan command dengan jelas. Error type sengaja ditangkap di npm run validate saat pre-push, sehingga ritme commit tidak terganggu tetapi perlindungan akhir tetap ada.
Ringkasan
Husky + lint-staged adalah pagar kualitas praktis untuk workflow Claude Code. Jaga pre-commit tetap ringan, pindahkan check mahal ke pre-push atau CI, dan tulis pembagian itu di prompt Claude Code. Dengan begitu hook menjadi standar tim, bukan hambatan lokal.
Langkah berikutnya adalah memperkuat aturan di panduan ESLint dan menyatukan format dengan panduan Prettier.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.