BEST-PRACTICES DOCS
CLEAN-CODE
Name
Description
Example
Output
Nama Variabel yang BermaknaDescription: Gunakan nama yang menjelaskan maksud, bukan singkatan misterius.
Example:
// ❌ const d = 30 // ✅ const daysSinceLastLogin = 30
Output: Kode langsung dipahami
Nama Variabel yang BermaknaGunakan nama yang menjelaskan maksud, bukan singkatan misterius.
// ❌ const d = 30 // ✅ const daysSinceLastLogin = 30
Kode langsung dipahami
Fungsi Kecil (Single Responsibility)Description: Setiap fungsi hanya melakukan satu hal dengan baik.
Example:
// ❌
function processAndSave(data) { ... }
// ✅
function validate(data) { ... }
function save(data) { ... }Output: Mudah diuji dan dipelihara
Fungsi Kecil (Single Responsibility)Setiap fungsi hanya melakukan satu hal dengan baik.
// ❌
function processAndSave(data) { ... }
// ✅
function validate(data) { ... }
function save(data) { ... }Mudah diuji dan dipelihara
Hindari Magic NumbersDescription: Ganti angka mentah dengan konstanta bernama.
Example:
// ❌ if (user.age > 17) // ✅ const MINIMUM_ADULT_AGE = 18 if (user.age >= MINIMUM_ADULT_AGE)
Output: Makna jelas
Hindari Magic NumbersGanti angka mentah dengan konstanta bernama.
// ❌ if (user.age > 17) // ✅ const MINIMUM_ADULT_AGE = 18 if (user.age >= MINIMUM_ADULT_AGE)
Makna jelas
Komentar Menjelaskan 'Kenapa', bukan 'Apa'Description: Kode yang baik sudah menjelaskan apa yang dilakukan.
Example:
// ❌ // set x ke 5 let x = 5 // ✅ // Batas throttle agar tidak membanjiri API const THROTTLE_LIMIT = 5
Output: Komentar bernilai
Komentar Menjelaskan 'Kenapa', bukan 'Apa'Kode yang baik sudah menjelaskan apa yang dilakukan.
// ❌ // set x ke 5 let x = 5 // ✅ // Batas throttle agar tidak membanjiri API const THROTTLE_LIMIT = 5
Komentar bernilai
Gunakan Early ReturnDescription: Kurangi nesting dengan validasi di awal dan return cepat.
Example:
// ❌
function getData(user) {
if (user) {
if (user.active) {
return user.data
}
}
}
// ✅
function getData(user) {
if (!user || !user.active) return null
return user.data
}Output: Kode rata, mudah dibaca
Gunakan Early ReturnKurangi nesting dengan validasi di awal dan return cepat.
// ❌
function getData(user) {
if (user) {
if (user.active) {
return user.data
}
}
}
// ✅
function getData(user) {
if (!user || !user.active) return null
return user.data
}Kode rata, mudah dibaca
SOLID-PRINCIPLES
Name
Description
Example
Output
S - Single ResponsibilityDescription: Kelas / modul hanya punya satu alasan untuk berubah.
Example:
class UserRepository { ... }
class EmailService { ... }Output: Pemisahan tanggung jawab
S - Single ResponsibilityKelas / modul hanya punya satu alasan untuk berubah.
class UserRepository { ... }
class EmailService { ... }Pemisahan tanggung jawab
O - Open/ClosedDescription: Terbuka untuk ekstensi, tertutup untuk modifikasi.
Example:
class Discount {
getDiscount() { return 0 }
}
class SeasonalDiscount extends Discount {
getDiscount() { return 10 }
}Output: Tambah diskon tanpa ubah kode lama
O - Open/ClosedTerbuka untuk ekstensi, tertutup untuk modifikasi.
class Discount {
getDiscount() { return 0 }
}
class SeasonalDiscount extends Discount {
getDiscount() { return 10 }
}Tambah diskon tanpa ubah kode lama
L - Liskov SubstitutionDescription: Subclass harus bisa menggantikan parent class tanpa mengubah perilaku.
Example:
function printArea(shape: Shape) {
console.log(shape.area())
}Output: Setiap turunan Shape aman dipakai
L - Liskov SubstitutionSubclass harus bisa menggantikan parent class tanpa mengubah perilaku.
function printArea(shape: Shape) {
console.log(shape.area())
}Setiap turunan Shape aman dipakai
I - Interface SegregationDescription: Jangan paksa client mengimplementasi method yang tidak dipakai.
Example:
interface Printer { print() }
interface Scanner { scan() }
class AllInOne implements Printer, Scanner {}Output: Interface terpisah
I - Interface SegregationJangan paksa client mengimplementasi method yang tidak dipakai.
interface Printer { print() }
interface Scanner { scan() }
class AllInOne implements Printer, Scanner {}Interface terpisah
D - Dependency InversionDescription: Modul tingkat tinggi tidak bergantung pada modul tingkat rendah, tapi pada abstraksi.
Example:
class Service {
constructor(private repo: Repository) {}
}Output: Ganti database tanpa ubah Service
D - Dependency InversionModul tingkat tinggi tidak bergantung pada modul tingkat rendah, tapi pada abstraksi.
class Service {
constructor(private repo: Repository) {}
}Ganti database tanpa ubah Service
DESIGN-PATTERNS
Name
Description
Example
Output
Module PatternDescription: Enkapsulasi kode dalam modul ES6/CommonJS.
Example:
export function helper() { ... }Output: Kode terisolasi
Module PatternEnkapsulasi kode dalam modul ES6/CommonJS.
export function helper() { ... }Kode terisolasi
SingletonDescription: Satu instance untuk seluruh aplikasi (Prisma client).
Example:
import { PrismaClient } from '@prisma/client'
export const prisma = new PrismaClient()Output: Satu koneksi database
SingletonSatu instance untuk seluruh aplikasi (Prisma client).
import { PrismaClient } from '@prisma/client'
export const prisma = new PrismaClient()Satu koneksi database
Repository PatternDescription: Abstraksi akses data di balik interface.
Example:
class UserRepo {
async findById(id) { ... }
}Output: Ganti ORM tanpa ubah service
Repository PatternAbstraksi akses data di balik interface.
class UserRepo {
async findById(id) { ... }
}Ganti ORM tanpa ubah service
Observer / Pub-SubDescription: Objek memberi tahu subscriber ketika terjadi perubahan.
Example:
eventEmitter.on('order.placed', sendEmail)
eventEmitter.emit('order.placed', order)Output: Reaksi terpisah dari pemicu
Observer / Pub-SubObjek memberi tahu subscriber ketika terjadi perubahan.
eventEmitter.on('order.placed', sendEmail)
eventEmitter.emit('order.placed', order)Reaksi terpisah dari pemicu
GIT-BEST-PRACTICES
Name
Description
Example
Output
Conventional CommitsDescription: Format commit: type(scope): message.
Example:
feat(auth): add login with Google fix(cart): resolve zero quantity bug
Output: Changelog otomatis
Conventional CommitsFormat commit: type(scope): message.
feat(auth): add login with Google fix(cart): resolve zero quantity bug
Changelog otomatis
Branch Naming ConventionDescription: Nama cabang: type/description.
Example:
feature/user-profile bugfix/login-error chore/update-deps
Output: CI/CD terpicu tepat
Branch Naming ConventionNama cabang: type/description.
feature/user-profile bugfix/login-error chore/update-deps
CI/CD terpicu tepat
Commit Kecil & FokusDescription: Satu commit satu perubahan logis.
Example:
git commit -m 'add email validation' git commit -m 'style: format with prettier'
Output: Mudah di-review & revert
Commit Kecil & FokusSatu commit satu perubahan logis.
git commit -m 'add email validation' git commit -m 'style: format with prettier'
Mudah di-review & revert
Pull Request TemplateDescription: Gunakan template PR untuk konsistensi.
Example:
## Deskripsi ## Cara Test ## Screenshot
Output: Informasi lengkap
Pull Request TemplateGunakan template PR untuk konsistensi.
## Deskripsi ## Cara Test ## Screenshot
Informasi lengkap
SECURITY-BEST-PRACTICES
Name
Description
Example
Output
Jangan Commit SecretDescription: Simpan semua kredensial di environment variable.
Example:
# .env DATABASE_URL=postgres://... # jangan commit .env
Output: Kredensial aman
Jangan Commit SecretSimpan semua kredensial di environment variable.
# .env DATABASE_URL=postgres://... # jangan commit .env
Kredensial aman
Validasi Input PenggunaDescription: Selalu validasi & sanitasi input dari client.
Example:
import { z } from 'zod'
const schema = z.object({ email: z.string().email() })
schema.parse(req.body)Output: Input aman diproses
Validasi Input PenggunaSelalu validasi & sanitasi input dari client.
import { z } from 'zod'
const schema = z.object({ email: z.string().email() })
schema.parse(req.body)Input aman diproses
HTTPS EverywhereDescription: Semua komunikasi harus melalui HTTPS.
Example:
vercel.json: { "headers": [...] }Output: Data terenkripsi
HTTPS EverywhereSemua komunikasi harus melalui HTTPS.
vercel.json: { "headers": [...] }Data terenkripsi
CORS yang KetatDescription: Batasi origin yang boleh mengakses API.
Example:
Access-Control-Allow-Origin: https://appkamu.com
Output: Hanya domainmu
CORS yang KetatBatasi origin yang boleh mengakses API.
Access-Control-Allow-Origin: https://appkamu.com
Hanya domainmu
ACCESSIBILITY
Name
Description
Example
Output
Gunakan Semantic HTMLDescription: Gunakan <header>, <main>, <nav>, <footer>.
Example:
<header><h1>Logo</h1><nav>...</nav></header>
Output: Screen reader paham struktur
Gunakan Semantic HTMLGunakan <header>, <main>, <nav>, <footer>.
<header><h1>Logo</h1><nav>...</nav></header>
Screen reader paham struktur
Alt pada GambarDescription: Setiap gambar harus punya alt yang deskriptif.
Example:
<img src="chart.png" alt="Grafik penjualan kuartal 3" />
Output: Dibaca screen reader
Alt pada GambarSetiap gambar harus punya alt yang deskriptif.
<img src="chart.png" alt="Grafik penjualan kuartal 3" />
Dibaca screen reader
Label pada FormDescription: Semua input harus memiliki label.
Example:
<label htmlFor="email">Email</label> <input id="email" type="email" />
Output: Terhubung dengan input
Label pada FormSemua input harus memiliki label.
<label htmlFor="email">Email</label> <input id="email" type="email" />
Terhubung dengan input
Kontras Warna CukupDescription: Rasio kontras minimal 4.5:1 untuk teks normal.
Example:
Warna teks #333 di atas background #fff → rasio 12.6:1
Output: Terbaca oleh semua
Kontras Warna CukupRasio kontras minimal 4.5:1 untuk teks normal.
Warna teks #333 di atas background #fff → rasio 12.6:1
Terbaca oleh semua
PERFORMANCE
Name
Description
Example
Output
Lazy Loading KomponenDescription: Gunakan dynamic import untuk komponen berat.
Example:
const Heavy = dynamic(() => import('./Heavy'))Output: Bundle lebih kecil
Lazy Loading KomponenGunakan dynamic import untuk komponen berat.
const Heavy = dynamic(() => import('./Heavy'))Bundle lebih kecil
Optimasi GambarDescription: Gunakan format modern (WebP) dan resize sesuai kebutuhan.
Example:
next/image secara otomatis mengoptimasi
Output: Page load cepat
Optimasi GambarGunakan format modern (WebP) dan resize sesuai kebutuhan.
next/image secara otomatis mengoptimasi
Page load cepat
Caching DataDescription: Cache fetch atau database query yang jarang berubah.
Example:
fetch(url, { next: { revalidate: 3600 } })Output: Respons instan
Caching DataCache fetch atau database query yang jarang berubah.
fetch(url, { next: { revalidate: 3600 } })Respons instan
Hindari Bundle BerlebihDescription: Analisis bundle dengan @next/bundle-analyzer.
Example:
const withBundleAnalyzer = require('@next/bundle-analyzer')()Output: Hapus library tidak terpakai
Hindari Bundle BerlebihAnalisis bundle dengan @next/bundle-analyzer.
const withBundleAnalyzer = require('@next/bundle-analyzer')()Hapus library tidak terpakai
SOFT-SKILLS
Name
Description
Example
Output
Komunikasi yang JelasDescription: Tulis pesan commit, deskripsi PR, dan komentar yang informatif.
Example:
PR: 'Menambahkan validasi email pada form registrasi'
Output: Tim langsung paham
Komunikasi yang JelasTulis pesan commit, deskripsi PR, dan komentar yang informatif.
PR: 'Menambahkan validasi email pada form registrasi'
Tim langsung paham
Pair ProgrammingDescription: Kerjakan masalah rumit bersama-sama.
Example:
Satu menulis kode, satu meninjau langsung
Output: Bug lebih sedikit
Pair ProgrammingKerjakan masalah rumit bersama-sama.
Satu menulis kode, satu meninjau langsung
Bug lebih sedikit
Terima FeedbackDescription: Code review adalah sarana belajar, bukan kritik pribadi.
Example:
'Oh iya, ternary ini bisa dibuat lebih jelas, terima kasih masukannya'
Output: Tim tumbuh bersama
Terima FeedbackCode review adalah sarana belajar, bukan kritik pribadi.
'Oh iya, ternary ini bisa dibuat lebih jelas, terima kasih masukannya'
Tim tumbuh bersama
FOLDER-STRUCTURE
Name
Description
Example
Output
Feature-based StructureDescription: Kelompokkan berdasarkan fitur: user, product, order.
Example:
src/features/user/components/ src/features/user/hooks/
Output: Navigasi cepat
Feature-based StructureKelompokkan berdasarkan fitur: user, product, order.
src/features/user/components/ src/features/user/hooks/
Navigasi cepat
Pisahkan Server & ClientDescription: Server component di root, client component di subfolder.
Example:
app/page.tsx (server)
app/ui/button.tsx ('use client')Output: Batas jelas
Pisahkan Server & ClientServer component di root, client component di subfolder.
app/page.tsx (server)
app/ui/button.tsx ('use client')Batas jelas
NAMING-CONVENTIONS
Name
Description
Example
Output
camelCase untuk Variabel & FungsiDescription: let userName = 'ridho'
Example:
function getUserById(id: string) {}Output: Konsisten
camelCase untuk Variabel & Fungsilet userName = 'ridho'
function getUserById(id: string) {}Konsisten
PascalCase untuk Komponen & ClassDescription: export default function UserProfile() {}
Example:
class DatabaseConnection {}Output: Mudah dikenali
PascalCase untuk Komponen & Classexport default function UserProfile() {}
class DatabaseConnection {}Mudah dikenali
UPPER_CASE untuk KonstantaDescription: const API_TIMEOUT = 5000
Example:
const MAX_RETRY_ATTEMPTS = 3
Output: Konstanta global
UPPER_CASE untuk Konstantaconst API_TIMEOUT = 5000
const MAX_RETRY_ATTEMPTS = 3
Konstanta global
CODE-REVIEW
Name
Description
Example
Output
Review dengan EmpatiDescription: Fokus pada kode, bukan orangnya. Beri saran, bukan perintah.
Example:
'Mungkin kita bisa...' daripada 'Harusnya...'
Output: Tim nyaman
Review dengan EmpatiFokus pada kode, bukan orangnya. Beri saran, bukan perintah.
'Mungkin kita bisa...' daripada 'Harusnya...'
Tim nyaman
Cek Tes Terlebih DahuluDescription: Pastikan semua test lulus sebelum review logic.
Example:
pnpm test -- --coverage
Output: Kualitas terjaga
Cek Tes Terlebih DahuluPastikan semua test lulus sebelum review logic.
pnpm test -- --coverage
Kualitas terjaga