Episode ini membahas strategi multiplatform dan shared libraries di Dart: berbagi kode antara mobile, web, server, dan CLI, arsitektur modular dengan package yang dapat dipakai ulang, testing cross-platform, serta integrasi dengan Flutter plugins.

Salah satu janji terbesar Dart terwujud ketika kode yang sama berjalan di mobile, web, server, dan command line. Episode 17 membahas strategi multiplatform dan shared libraries: bagaimana memisahkan logika dari platform, menyusun project modular, menguji lintas platform, dan terhubung dengan Flutter plugins.
Kunci semua ini adalah disiplin: kode yang dibagi harus murni dan bebas dependency platform. Kalian akan belajar memisahkan lapisan dengan benar sehingga satu paket logika melayani semua klien.
Inti strategi multiplatform adalah memisahkan logika bisnis (yang murni Dart) dari detail platform (UI, file, jaringan native):
monorepo/
├── packages/domain_core/ # murni Dart, dipakai semua platform
├── apps/flutter_app/ # mobile dan web via Flutter
├── apps/server/ # backend dengan Shelf
└── apps/cli/ # command-line toolpackages/domain_core/ adalah pure Dart package tanpa dependency Flutter atau io spesifik. Setiap aplikasi menambahkan package ini sebagai dependency dan memakai logika yang sama persis di semua platform.
Agar package bisa dibagi, patuhi aturan: hindari dart:io dan dart:html di lapisan core — keduanya hanya tersedia di sebagian platform. Untuk operasi yang bergantung platform, definisikan abstraksi (interface) di core dan berikan implementasi konkret per platform.
Dart mendukung project multi-package dalam satu monorepo. Struktur umum memakai packages/ yang berisi library yang dapat dipakai ulang:
name: apps_flutter
dependencies:
domain_core:
path: ../../packages/domain_coredomain_core ditambahkan dengan path: sehingga perubahan di package langsung terlihat tanpa publish. Setiap package punya pubspec.yaml dan siklus versioning sendiri.
Paket yang baik punya satu tanggung jawab: domain, data access, atau presentasi. Batas yang jelas memungkinkan tim mengerjakan bagian berbeda tanpa saling melangkahi, dan memudahkan pengujian karena dependensi bisa di-mock.
Mulai dengan dua package saja — satu untuk domain dan satu untuk aplikasi — lalu pecah lebih lanjut saat tim dan fitur tumbuh. Batas package yang dipaksakan terlalu dini justru menambah biaya koordinasi tanpa manfaat nyata.
Karena semua platform memakai logika yang sama, uji package core sekali dan hasilnya berlaku untuk semua klien:
cd packages/domain_core
dart testdart test di package core memvalidasi logika yang dipakai Flutter, server, dan CLI sekaligus. Ini penghematan besar dibanding menulis test terpisah per platform.
Kombinasi ketiganya menghasilkan lapisan yang bisa diuji terpisah: repository memakai interface dari core, dan aplikasi menyuntikkan implementasi berbasis HTTP atau database sesuai platform. Alur ini membuat penggantian sumber data tidak menyentuh logika bisnis sama sekali.
Kebutuhan khusus platform ditangani lewat Flutter plugins. Plugin menggabungkan kode Dart dengan implementasi native Android, iOS, dan lainnya:
import 'package:shared_preferences/shared_preferences.dart';
Future<void> simpanPref() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('tema', 'gelap');
}SharedPreferences.getInstance() adalah contoh plugin populer yang menyediakan API Dart di atas implementasi native per platform.
Untuk membuat plugin: flutter create --template=plugin. Plugin menghasilkan API Dart di folder lib/, implementasi Android di android/, iOS di ios/, dan seterusnya. Platform channel menghubungkan keduanya. Jika logika platform semakin kompleks, pertimbangkan FFI (episode 16) sebagai alternatif yang lebih portabel.
Karena plugin menyentuh banyak platform, pastikan setiap perubahan diuji di seluruh target. Mulai dari template bawaan, lalu tambahkan fungsionalitas platform satu per satu — ini menjaga plugin tetap kecil dan mudah dipelihara.
Jangan menaruh logika bisnis di dalam plugin. Taruh di package core, dan biarkan plugin hanya menjadi jembatan tipis ke kemampuan native.
Inti yang harus dibawa pulang:
dart:io dan dart:html di lapisan yang dibagi lintas platform.packages/ dan dependency path memudahkan pengembangan modular.Di episode 18 selanjutnya kita akan membahas ekosistem ekstensi dan komunitas — package populer seperti dio, freezed, dan Riverpod, bekerja dengan pub.dev dan publishing package, berkontribusi ke open source Dart, serta sumber belajar dan kanal komunitas.