Episode ini membahas arsitektur aplikasi dan struktur berbasis fitur, desain komponen modular dengan pola atomik, organisasi domain-driven, serta design system dan library komponen UI untuk aplikasi yang mudah diskalakan.

Aplikasi kecil mudah ditulis, tapi aplikasi besar harus dirawat. Ketika kode bertambah ribuan baris, struktur yang buruk membuat setiap perubahan berisiko dan memperlambat tim. Arsitektur adalah jawaban: keputusan terstruktur tentang bagaimana kode diorganisir.
Episode 18 membahas arsitektur aplikasi dan struktur berbasis fitur, desain komponen modular dengan pola atomik, organisasi domain-driven, serta design system dan library komponen UI.
Daripada mengelompokkan file berdasarkan jenis teknis (semua komponen di satu folder), organisasi berbasis fitur mengelompokkan file berdasarkan domain bisnis:
app/
auth/
blog/
dashboard/
components/
ui/
forms/
layout/
lib/
api/
utils/
auth.tsStruktur di atas menempatkan route, komponen, dan logika setiap fitur berdekatan. Saat fitur blog berkembang, seluruh kode blog yang berkaitan tumbuh bersama tanpa menyentuh fitur lain — memudahkan refactor dan on-boarding developer baru. Struktur ini juga membuat penghapusan fitur menjadi sederhana: hapus folder fitur beserta seluruh isinya tanpa khawatir sisa kode tersebar.
Komponen server dan klien juga memengaruhi struktur: logika data berada di server, interaksi di klien. Pemisahan ini menjaga batas keamanan sekaligus memperjelas tanggung jawab tiap file.
Evaluasi arsitektur secara berkala: apakah folder yang ada masih mencerminkan kebutuhan tim? Arsitektur adalah dokumen hidup yang harus beradaptasi, bukan artefak yang membeku di awal project.
App Router menyediakan route groups dengan folder berkurung, misalnya (marketing) dan (app). Route groups mengatur file tanpa menambah segment URL, sekaligus memungkinkan layout terpisah antar grup — pola yang sering dipakai untuk memisahkan halaman publik dan halaman terproteksi. Grup (app) bisa membawa layout dashboard sendiri, sementara (marketing) memakai layout publik — keduanya tetap berbagi layout akar yang sama.
Pola atomic design membagi komponen dalam lima level: atom, molekul, organisme, template, dan halaman. Contohnya:
Pola ini mendorong komponen kecil yang reusable. Komponen primitif seperti Input dan Button adalah contoh atom yang bisa dipakai di seluruh fitur. Karena JSX di Next.js identik dengan React, seluruh pola ini berlaku langsung di komponen server maupun klien.
Komponen modular didesain lewat composition — menggabungkan komponen kecil — daripada konfigurasi props yang makin besar. Gunakan props children untuk membiarkan pemanggil menentukan isi komponen, dan props eksplisit untuk opsi yang memang dikendalikan komponen. Pisahkan komponen presentasional (hanya tampilan) dari komponen container (yang mengambil data). Ini membuat komponen tampilan mudah diuji dan dipakai ulang di berbagai konteks.
Domain-driven design (DDD) mengorganisir kode di sekitar domain bisnis: perawatan, keuangan, edukasi, dan sebagainya. Setiap domain memiliki bahasa yang sama antara developer dan stakeholder, dan setiap modul memiliki batas yang jelas. Di Next.js, ini berarti folder fitur mencerminkan domain, dan lib/ dipecah per domain alih-alih satu folder util yang campur aduk. Mulai dari domain paling kompleks — biasanya yang paling sering berubah — dan buat batas yang jelas antara domain serta infrastruktur seperti database dan API eksternal agar perubahan satu sisi tidak merembet ke sisi lain.
Untuk project yang benar-benar besar, pertimbangkan monorepo dengan pnpm workspaces atau Turborepo — memisahkan aplikasi Next.js, pustaka komponen, dan API ke package terpisah dengan versioning sendiri. Pada skala menengah, struktur berbasis fitur sederhana sudah cukup; DDD dan monorepo adalah alat untuk project yang benar-benar besar.
Design system adalah kumpulan token, komponen, dan pedoman yang menjaga konsistensi. Komponen utamanya:
Tokeng dibuat di CSS:
:root {
--color-primary: #2563eb;
--radius-md: 8px;
--font-sans: "Inter", system-ui, sans-serif;
}Variabel CSS di atas dipakai seluruh komponen, sehingga perubahan branding cukup mengubah satu tempat. Tokens memisahkan keputusan visual dari implementasi komponen. Mulai dari tokens, lalu komponen primitif, lalu komponen kompleks — jangan membangun seluruh sistem sekaligus, kembangkan berdasarkan kebutuhan fitur yang nyata, bukan spekulasi.
Membangun design system dari nol butuh investasi besar. Alternatif pragmatis: gunakan library seperti shadcn/ui yang menyediakan komponen aksesibel dan bisa disalin ke codebase, atau Radix UI sebagai fondasi headless yang tidak mengikat styling. Mulai dari library, lalu kustomisasi bertahap untuk kebutuhan brand.
Komponen primitif wajib aksesibel sejak awal — memperbaiki aksesibilitas di akhir jauh lebih mahal daripada membangunnya dengan benar.
Pola yang sama berlaku untuk tokens: definisikan hanya yang dipakai, dan bersihkan yang tidak terpakai agar sistem tetap ringan.
Inti yang harus dibawa pulang:
Di episode 19 selanjutnya kita akan membahas tooling modern dan build automation — build tooling dengan Turbopack, konfigurasi TypeScript strict, pipeline CI/CD untuk project Next.js, serta linting, formatting, dan pre-commit hooks. Alur pengembangan kalian akan diotomatisasi.