Episode ini membedah arsitektur Svelte: bagaimana compiler mengubah deklarasi reaktif menjadi kode imperative, struktur file .svelte, reactive declarations dan store, lifecycle hooks, serta mekanisme scoped CSS. Ini adalah fondasi yang dipakai semua episode berikutnya.

Di episode 1 kalian tahu bahwa Svelte adalah compiler. Episode 2 masuk lebih dalam: apa yang sebenarnya terjadi saat compiler bekerja, dan bagaimana sebuah komponen .svelte disusun. Kalau kalian memahami arsitektur ini, sintaks Svelte yang tampak ajaib akan terlihat sebagai transformasi kode yang sistematis.
Reaktivitas Svelte bukan sihir. Ia adalah hasil kompilasi yang cermat: compiler membaca deklarasi kalian, melacak ketergantungan antar variabel, lalu menghasilkan kode update DOM yang langsung dan efisien. Memahami alur ini membantu kalian menulis komponen yang tepat guna dan menghindari kesalahan yang umum terjadi.
Episode ini membahas cara kerja compiler, struktur komponen, reactive declarations, lifecycle hooks, dan scoped CSS. Kita juga menyentuh store sebagai mekanisme state lintas komponen yang akan dibedah penuh di episode 6.
Kalian menulis komponen secara deklaratif — "tampilkan nilai ini" — tanpa memberi tahu browser bagaimana caranya. Compiler Svelte membaca deklarasi itu dan mengubahnya menjadi kode imperative yang langsung dimengerti browser.
<script>
let pesan = "Halo Svelte"
</script>
<h1>{pesan}</h1>let pesan = "Halo Svelte" adalah deklarasi state. Saat build, compiler melihat bahwa <h1>{pesan}</h1> bergantung pada pesan, lalu menghasilkan fungsi update yang menulis nilai pesan langsung ke elemen <h1> saat berubah. Tidak ada proses diffing di runtime.
Karena compiler sudah tahu letak setiap ketergantungan, pembaruan DOM dilakukan secara presisi. Ketika pesan berubah, hanya elemen <h1> yang diperbarui — bukan seluruh subtree. Inilah perbedaan fundamental dengan React dan Vue yang melakukan perbandingan virtual DOM di browser.
Bayangkan daftar 10.000 item. Di React, framework membandingkan pohon virtual lama dan baru untuk mencari perbedaan. Di Svelte, compiler menghasilkan kode yang menambahkan, menghapus, atau mengubah hanya elemen yang benar-benar berubah. Efeknya terasa terutama di aplikasi dengan banyak state update.
Compiler menganalisis semua penggunaan variabel di dalam komponen dan membangun grafik ketergantungan. Saat sebuah variabel diubah, compiler tahu persis variabel turunan dan elemen DOM mana yang harus diperbarui. Grafik ini dibangun saat build, sehingga tidak ada runtime yang harus menghitungnya di browser.
Dengan runes di Svelte 5, kompiler memahami sintaks seperti $state dan $derived secara eksplisit, membuat tracking ini lebih jelas dan bekerja di mana saja — termasuk di dalam modul .js biasa, bukan hanya komponen.
Sebuah file .svelte terdiri dari tiga blok: script, markup, dan style. Markup adalah inti komponen; script menyediakan logika; style menata tampilan.
<script>
let nama = "Svelte"
</script>
<div class="kartu">
<h1>Halo {nama}</h1>
</div>
<style>
.kartu {
padding: 1rem;
border-radius: 8px;
}
</style>{nama} di dalam markup adalah interpolation: nilainya disisipkan ke teks. Blok <style> terlihat seperti CSS biasa, tapi ada keistimewaan besar yang akan kita bahas di bagian scoped CSS.
Ada dua tipe script dalam Svelte 5: <script> biasa untuk instance komponen, dan <script module> untuk kode yang dijalankan sekali saat modul dimuat — cocok untuk state lintas instance. Gunakan <script module> untuk konstanta, helper, atau store yang dibagikan antar instance komponen yang sama.
Sebelum runes, Svelte memakai $: untuk mendeklarasikan nilai turunan. Sintaks ini masih berfungsi di Svelte 5 dalam mode legacy:
<script>
let harga = 1000
$: pajak = harga * 0.11
</script>
<p>Total: {harga + pajak}</p>$: pajak = harga * 0.11 berarti "setiap kali harga berubah, hitung ulang pajak". Di mode runes modern, ekspresi serupa ditulis let pajak = $derived(harga * 0.11). Konsepnya sama: nilai yang dihitung otomatis dari nilai lain.
Store adalah objek yang membawa state dan dapat di-subscribe dari mana saja. Saat state berubah, semua yang subscribe menerima nilai baru. Kalian akan banyak memakai writable, readable, dan derived dari svelte/store.
import { writable } from "svelte/store"
export const hitung = writable(0)writable(0) membuat store dengan nilai awal 0. Di episode 6 kita akan membahas store secara lengkap: kapan memakainya, bagaimana menulis custom store, dan kapan runes $state lebih cocok.
Komponen Svelte melewati siklus hidup: dibuat, diperbarui, dan dihancurkan. Lifecycle hooks dipakai untuk menangkap momen tersebut:
onMount — dijalankan setelah komponen dipasang ke DOM; tempat ideal untuk fetching data.beforeUpdate — tepat sebelum DOM diperbarui.afterUpdate — tepat setelah DOM diperbarui.onDestroy — saat komponen dihancurkan; tempat membersihkan timer, listener, dan subscription.tick — menunggu pembaruan state selesai dirender.<script>
import { onMount, onDestroy } from "svelte"
let detik = 0
let timer
onMount(() => {
timer = setInterval(() => (detik += 1), 1000)
})
onDestroy(() => clearInterval(timer))
</script>
<p>Sudah berjalan {detik} detik</p>import { onMount, onDestroy } from "svelte" mengambil hook dari package svelte. onDestroy(() => clearInterval(timer)) mencegah kebocoran memori dengan membersihkan timer saat komponen hilang — kebiasaan wajib untuk komponen produksi.
CSS di dalam <style> komponen otomatis di-scope: compiler menambahkan class hash ke setiap elemen yang terpengaruh, sehingga style tidak merembes ke komponen lain. Ini menyelesaikan masalah global CSS tanpa perlu nama class yang rumit seperti BEM.
<style>
.kartu {
background: #fff;
}
</style>.kartu {: ... } di atas hanya berlaku untuk elemen dengan class kartu di dalam komponen ini. Di balik layar, compiler mengubah selektornya menjadi sesuatu seperti .kartu.svelte-abc123. Tidak ada tabrakan antar komponen.
Kadang kalian memang ingin menargetkan elemen di luar komponen — misalnya mengubah style elemen library. Gunakan :global:
:global(.modal-backdrop) {
background: rgba(0, 0, 0, 0.5);
}:global(.modal-backdrop) membuat selektor tersebut tidak di-scope. Gunakan secukupnya — terlalu banyak :global berarti kalian melawan sistem yang seharusnya membantu.
Inti yang harus dibawa pulang:
.svelte terdiri dari script, markup, dan style; <script module> untuk logika berbagi.onMount, afterUpdate, onDestroy) mengatur momen penting komponen.:global hanya saat benar-benar perlu.Di episode 3 selanjutnya kita akan memulai proyek Svelte sungguhan — membuat aplikasi dengan npm create svelte@latest, memahami struktur src/routes, src/lib, dan static, menjalankan dev server dengan hot reload, serta menyiapkan TypeScript, ESLint, dan Prettier. Sampai jumpa di episode berikutnya!