Episode ini membedah cara kerja Dart di balik layar: runtime dengan model JIT dan AOT, struktur program berbasis library dan package, sistem tipe dengan sound typing, serta fondasi Future dan Stream untuk asynchronous programming.

Untuk menjadi mahir Dart, kalian perlu paham apa yang terjadi di balik layar: bagaimana kode kalian dieksekusi, bagaimana program disusun, dan bagaimana sistem tipe melindungi kalian dari bug. Episode 2 membedah arsitektur bahasa Dart dari runtime hingga sistem tipe.
Kita akan membahas model kompilasi JIT dan AOT, struktur program yang berbasis library dan package, konsep sound typing beserta null safety, serta fondasi Future dan Stream. Materi ini adalah lensa yang akan membuat semua episode berikutnya terasa masuk akal.
Jangan khawatir jika ada istilah yang terasa abstrak. Fokuskan pemahaman pada konsep, sementara detail sintaks akan kalian kuasai di episode 4 sampai 7.
Selama pengembangan, kode Dart dijalankan di Dart VM menggunakan JIT (Just-In-Time). JIT mengkompilasi kode saat aplikasi berjalan, memungkinkan fitur seperti hot reload dan hot restart di Flutter, serta dart run yang langsung mengeksekusi skrip. Kecepatan memulai yang instan membuat loop pengembangan terasa ringan.
Saat aplikasi siap dirilis, Dart bisa dikompilasi AOT (Ahead-Of-Time) menjadi kode mesin native. AOT menghilangkan biaya kompilasi saat runtime sehingga startup lebih cepat, memori lebih stabil, dan performa lebih terprediksi. Perintah yang dipakai:
dart compile exe bin/app.dart -o bin/appHasilnya adalah executable native yang tidak membutuhkan Dart SDK untuk berjalan. Perintah dart compile exe bin/app.dart menghasilkan file biner yang langsung bisa dijalankan di mesin target tanpa runtime terpisah.
Untuk web, Dart dikompilasi menjadi JavaScript oleh dart compile js. Sementara untuk aplikasi Flutter, kode Dart dikompilasi ke kode mesin dan dijalankan di dalam Flutter engine yang ditulis dalam C++. Satu bahasa, banyak target: native, browser, dan mobile.
Semua kode Dart hidup di dalam library. Setiap file Dart adalah library implisit, dan kalian bisa menggabungkan library dengan import untuk memakai kode dari file atau package lain. Direktori lib/ adalah tempat kode yang bisa diimpor, sedangkan bin/ untuk entry point.
Ada juga mekanisme part untuk memecah satu library menjadi beberapa file — tapi praktik modern lebih menyarankan import daripada part. Berikut contoh struktur folder dari project yang dibuat dengan dart create:
my_app/
├── bin/my_app.dart
├── lib/my_app.dart
├── test/my_app_test.dart
├── pubspec.yaml
└── analysis_options.yamlStruktur ini sudah dibentuk oleh dart create my_app dan akan kita ekplorasi lebih jauh di episode 3 dan 8.
Di atas library, ada package — unit distribusi yang memiliki pubspec.yaml dan bisa dipublikasikan ke pub.dev. Package menggabungkan kode, metadata, dependency, dan tes. Konsep ini mirip crate di Rust atau npm package di JavaScript.
Dengan memahami hierarki ini — file, library, lalu package — kalian bisa menentukan di mana sebuah kode harus ditempatkan dan bagaimana ia diimpor oleh kode lain.
Dart adalah bahasa dengan sound typing: tipe sebuah variabel dijamin oleh kompiler, dan kesalahan tipe terdeteksi sebelum program dijalankan. Ditambah sound null safety, kompiler membedakan tipe nullable dan non-nullable, sehingga error null-pointer yang umum di bahasa lain dapat dicegah sejak waktu kompilasi.
Contoh singkat sistem tipe:
void main() {
String nama = 'Dart';
int versi = 3;
print('$nama versi $versi');
}Pada kode di atas, String nama menyatakan bahwa nama tidak akan pernah bernilai null. Jika kalian mencoba mengisi null, kompiler menolak sebelum aplikasi berjalan — itulah esensi sound typing yang akan kita bedah penuh di episode 6.
Jenis tipe di Dart terbagi dalam tiga kelompok utama: int, double, dan bool untuk nilai dasar, String untuk teks, serta tipe koleksi seperti List, Set, dan Map. Semua tipe ini tunduk pada aturan null safety dan sound typing yang sama, sehingga prinsip yang kalian pelajari berlaku konsisten di seluruh program.
Operasi seperti membaca file, memanggil HTTP, atau menunggu input jaringan tidak boleh memblokir thread utama. Dart menyelesaikannya dengan dua alat dasar:
Keduanya dikonsumsi dengan async dan await. Contoh penggunaan Future:
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 1));
return 'data siap';
}
void main() async {
var hasil = await fetchData();
print(hasil);
}await fetchData() menunda eksekusi tanpa memblokir thread, karena runtime menangguhkan fungsi tersebut. Detail lengkap async dan Stream akan dibahas di episode 7.
Inti yang harus dibawa pulang:
dart compile exe menghasilkan biner native tanpa runtime; dart compile js untuk web.pubspec.yaml.Future mewakili satu nilai masa depan; Stream mewakili banyak nilai seiring waktu.Di episode 3 selanjutnya kita akan menginstall dan menjalankan Dart secara langsung — verifikasi SDK, REPL dart repl, perintah dart run, pembuatan project dengan dart create, dan menambahkan dependency pertama ke pubspec.yaml. Siapkan terminal kalian untuk mulai mengeksekusi.