Mengapa Beralih dari HTMX ke Datastar
(everydaysuperpowers.dev)- Saat menggunakan HTMX, jumlah kode bisa dikurangi sekitar 70%, tetapi muncul masalah sinkronisasi antar-UI sekaligus meningkatnya kompleksitas manajemen state frontend
- Setelah mengadopsi Datastar, pengembangan aplikasi multiuser real-time menjadi lebih ringkas tanpa WebSockets dan lebih mudah dipelihara
- Sementara HTMX menyebarkan logika perilaku ke atribut-atribut HTML, Datastar meningkatkan konsistensi dan kemudahan pemeliharaan melalui model pembaruan yang dikendalikan server
- API Datastar terasa memiliki lebih sedikit atribut, sehingga keterbacaan kode dan produktivitas meningkat
- Datastar secara aktif memanfaatkan teknologi web native seperti Server-Sent Events(SSE), Web Components, dan CSS View Transitions untuk memungkinkan kolaborasi real-time dan struktur komponen yang dapat digunakan ulang
Pengantar dan motivasi
- Pada 2022, David Guillot di DjangoCon Europe membagikan kasus migrasi SaaS berbasis React ke HTMX, yang memangkas jumlah kode sekitar 70% sekaligus meningkatkan fitur
- Setelah itu, banyak tim merasakan bahwa saat beralih dari aplikasi single-page (SPA) ke aplikasi hypermedia multi-halaman, pengurangan kode tercapai dan pengalaman pengembang maupun pengguna sama-sama meningkat
- Penulis juga memindahkan proyek dari HTMX ke Datastar, dan mendapati bahwa kode menjadi lebih singkat serta pengembangan aplikasi multiuser real-time dimungkinkan tanpa WebSocket atau manajemen state yang rumit
Masalah yang memicu perpindahan
- Saat menyiapkan presentasi FlaskCon 2025, penulis mencoba menyinkronkan UI dengan menggabungkan HTMX dan AlpineJS, tetapi menghadapi masalah sinkronisasi UI
- Kedua library dibuat oleh pengembang yang berbeda sebagai alat yang terpisah, sehingga tidak bisa saling berkomunikasi dan pengembang harus menangani integrasinya sendiri
- Dalam proses menginisialisasi komponen di berbagai waktu dan mengoordinasikan event, ternyata dibutuhkan jauh lebih banyak kode dan waktu debugging dari perkiraan
- Penulis lalu tertarik mencoba Datastar karena ia menggabungkan fungsi kedua library itu sambil tetap hadir dengan ukuran di bawah 11KB
- Ini menguntungkan untuk meningkatkan performa pemuatan halaman bagi pengguna perangkat mobile
Desain API Datastar yang lebih baik
- API Datastar terasa jauh lebih ringan dibanding HTMX, dan jumlah atribut tambahan yang diperlukan untuk mendapatkan hasil yang diinginkan lebih sedikit
- HTMX membutuhkan banyak atribut untuk sebagian besar interaksi
- Definisi URL, penentuan elemen target, dan cara menangani respons masing-masing harus diatur lewat atribut terpisah
- Umumnya perlu 2~3 atribut setiap kali, dan kadang harus menelusuri rantai pewarisan untuk memahami cara kerja atribut tersebut
<a hx-target="#rebuild-bundle-status-button" hx-select="#rebuild-bundle-status-button" hx-swap="outerHTML" hx-trigger="click" hx-get="/rebuild/status-button"></a> - Datastar umumnya dapat mewujudkan fungsi yang sama hanya dengan satu atribut saja
<a data-on-click="@get('/rebuild/status-button')"></a>- Bahkan beberapa bulan kemudian saat melihat lagi kodenya, cara kerjanya tetap mudah dipahami
Perbedaan cara kerja
- HTMX adalah library frontend yang bertujuan memperluas spesifikasi HTML, sedangkan Datastar adalah library yang dikendalikan server yang bertujuan membangun aplikasi pembaruan real-time web native berperforma tinggi
- HTMX mendefinisikan perilaku dengan menambahkan atribut pada elemen yang memicu request, sehingga meskipun yang diperbarui adalah elemen yang jauh di tempat lain di halaman, logikanya tetap tersebar di beberapa lapisan
- Datastar membuat server yang menentukan apa yang harus diubah, sehingga seluruh logika pembaruan terpusat di satu tempat
-
Contoh HTMX
<div> <div id="alert"></div> <button hx-get="/info" hx-select="#info-details" hx-swap="outerHTML" hx-select-oob="#alert"> Get Info! </button> </div>- Saat tombol ditekan, request GET dikirim ke
/info, tombol diganti dengan elemen ber-IDinfo-detailsdari respons, dan elemen ber-IDalertdi halaman juga diganti dengan elemen dengan ID yang sama dari respons - Elemen tombol harus mengetahui terlalu banyak hal, dan karena harus tahu sebelumnya informasi apa yang akan dikembalikan server, prinsip "locality of behavior" milik HTMX pun melemah
- Saat tombol ditekan, request GET dikirim ke
-
Pendekatan Datastar yang ditingkatkan
<div> <div id="alert"></div> <button id="info-details" data-on-click="@get('/info')"> Get Info! </button> </div>- Server mengembalikan string HTML yang berisi dua elemen root dengan ID yang sama
<p id="info-details">These are the details you are looking for…</p> <div id="alert">Alert! This is a test.</div> - Sederhana dan memiliki performa yang baik
- Server mengembalikan string HTML yang berisi dua elemen root dengan ID yang sama
Berpikir di level komponen
- Pendekatan yang lebih baik adalah memperlakukan HTML sebagai komponen
- Pahami esensi komponen tersebut
- Cara pengguna mendapatkan informasi tambahan tentang item tertentu
- Saat pengguna menekan tombol, informasi ditampilkan atau error dirender jika informasi tidak ada; dalam kedua kasus itu, komponen masuk ke state statis
-
Memisahkan komponen berdasarkan state
- State placeholder:
<!-- info-component-placeholder.html --> <div id="info-component"> <button data-on-click="@get('/product/{{product.id}}/info')"> Get Info! </button> </div> - State tampilan informasi:
<!-- info-component-get.html --> <div id="info-component"> {% if alert %}<div id="alert">{{ alert }}</div>{% endif %} <p>{{product.additional_information}}</p> </div> - Saat server merender HTML, Datastar akan memperbarui halaman secara otomatis
- Berpikir di level komponen mencegah masuk ke state yang salah atau kehilangan state pengguna
- State placeholder:
Memperbarui beberapa komponen sekaligus
- Salah satu hal yang mengesankan dari presentasi David Guillot adalah ketika aplikasi memperbarui jumlah item favorit, komponen yang berubah dan elemen penghitung yang letaknya sangat jauh juga ikut diperbarui
- Di HTMX, ini memicu event JavaScript, yang kemudian memicu komponen jarak jauh untuk mengirim request GET
- Datastar memungkinkan memperbarui beberapa komponen sekaligus bahkan di dalam fungsi sinkron
-
Contoh keranjang belanja
- Komponen tambah ke keranjang:
<form id="purchase-item" data-on-submit="@post('/add-item', {contentType: 'form'})">" > <input type=hidden name="cart-id" value="{{cart.id}}"> <input type=hidden name="item-id" value="{{item.id}}"> <fieldset> <button data-on-click="$quantity -= 1">-</button> <label>Jumlah <input name=quantity type=number data-bind-quantity value=1> </label> <button data-on-click="$quantity += 1">+</button> </fieldset> <button type=submit>Tambahkan ke keranjang</button> {% if msg %} <p class=message>{{msg}}</p> {% endif %} </form> - Komponen tampilan jumlah keranjang:
<div id="cart-count"> <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"> <use href="#shoppingCart"> </svg> {{count}} </div> - Di Django, dua komponen diperbarui dalam request yang sama:
from datastar_py.consts import ElementPatchMode from datastar_py.django import ( DatastarResponse, ServerSentEventGenerator as SSE, ) def add_item(request): # pembaruan state penting dihilangkan return DatastarResponse([ SSE.patch_elements( render_to_string('purchase-item.html', context=dict(cart=cart, item=item, msg='Item added!')) ), SSE.patch_elements( render_to_string('cart-count.html', context=dict(count=item_count)) ), ])
- Komponen tambah ke keranjang:
Filosofi web native
- Melalui komunitas Datastar di Discord, penulis memahami bahwa Datastar bukan sekadar skrip helper, melainkan filosofi membangun aplikasi dengan memanfaatkan primitive dasar web
- Jika HTMX ingin mengembangkan spesifikasi HTML, Datastar lebih tertarik mendorong adopsi fitur web native
- CSS view transitions
- Server-Sent Events
- Web Components, dll.
- Penulis berhasil mencapai hasil besar dengan me-refactor komponen AlpineJS yang kompleks menjadi web component sederhana yang bisa diekstrak dan digunakan ulang di banyak tempat
- Ini adalah pola yang sangat baik untuk mencapai locality of behavior dan reusabilitas tinggi melalui pembuatan elemen HTML kustom, bahkan tanpa alat seperti React
Pembaruan real-time untuk aplikasi multiuser
- Aplikasi yang menjadikan kolaborasi sebagai fitur kelas satu berbeda dari aplikasi lain, dan Datastar menjawab tantangan ini
- Sebagian besar pengembang HTMX mengambil informasi dari server dengan polling atau menulis kode WebSocket kustom, yang menambah kompleksitas
- Datastar menggunakan teknologi web sederhana bernama Server-Sent Events(SSE) untuk mendorong pembaruan dari server ke klien yang terhubung
- Saat pengguna menambahkan komentar atau state berubah, server langsung memperbarui browser dengan kebutuhan kode tambahan yang minimal
- Dashboard real-time, panel admin, dan alat kolaborasi dapat dibangun tanpa JavaScript kustom
- Jika koneksi klien terputus, browser akan otomatis mencoba terhubung kembali tanpa perlu kode tambahan
- Server juga bisa diberi tahu tentang "event terakhir yang diterima"
Menghindari kompleksitas berlebihan
- Komunitas Datastar di Discord membantu memahami visi Datastar untuk pembuatan aplikasi web
- Pembaruan UI berbasis push
- Pengurangan kompleksitas
- Penanganan situasi kompleks secara lokal dengan alat seperti web components
- Komunitas itu juga membantu pengguna baru menyadari saat mereka mendekati masalah dengan cara yang terlalu rumit
Tips utama
- Jangan takut mengirim ulang seluruh komponen setelah dirender ulang
- Ini lebih mudah dan tidak banyak memengaruhi performa
- Kompresinya bisa lebih baik, dan browser sangat cepat dalam mem-parsing string HTML
- Server adalah sumber kebenaran state dan lebih kuat daripada browser
- Biarkan server menangani sebagian besar state; Anda mungkin tidak memerlukan signal reaktif sebanyak yang dibayangkan
- Web Components sangat bagus untuk mengenkapsulasi logika dalam elemen kustom dengan locality of behavior yang tinggi
- Animasi bidang bintang di header situs Datastar adalah contoh yang bagus
- Elemen
<ds-starfield>mengenkapsulasi seluruh kode animasi bidang bintang dan mengekspos tiga atribut untuk mengubah state internalnya - Datastar menggerakkan atribut tersebut saat input rentang berubah atau mouse bergerak di atas elemen
Potensi yang melampaui batasan
- Potensi yang dimungkinkan Datastar adalah hal yang paling menarik
- Komunitasnya secara rutin membuat proyek yang jauh melampaui batasan yang biasa dialami pengembang dengan alat lain
Contoh yang patut diperhatikan
- Demo pemantauan database di halaman contoh
- Dengan memanfaatkan hypermedia, demo ini sangat meningkatkan kecepatan dan penggunaan memori dibanding demo yang dipresentasikan di konferensi JavaScript
- 1 miliar checkbox karya Anders Murphy
- Ketika eksperimen 1 juta checkbox melebihi kapasitas server, ia memakai Datastar untuk mewujudkan 1 miliar checkbox di server murah
- Aplikasi web yang menampilkan data semua stasiun radar di Amerika Serikat
- Saat sinyal radar berubah, titik yang соответствует di UI berubah dalam waktu kurang dari 100 milidetik
- Lebih dari 800 ribu titik diperbarui per detik, dan pengguna dapat melakukan scrub hingga 1 jam ke belakang dengan latensi kurang dari 700 milidetik
- Fakta bahwa ini bisa dilakukan sebagai aplikasi hypermedia menunjukkan apa yang dimungkinkan oleh Datastar
Pengalaman penggunaan saat ini
- Penulis masih berada pada tahap eksplorasi Datastar, dan telah dengan cepat serta mudah mengimplementasikan penanganan AJAX pembaruan UI yang merupakan fungsi standar HTMX
- Berbagai pola untuk mencapai lebih banyak hal dengan Datastar sedang dipelajari dan diuji
- Selama puluhan tahun, penulis tertarik pada cara memberikan pengalaman pengguna yang lebih baik lewat pembaruan real-time, dan menyukai bahwa Datastar memungkinkan pembaruan berbasis push bahkan dalam kode sinkron
- Saat pertama mulai memakai HTMX, penulis merasakan kegembiraan besar, tetapi setelah beralih ke Datastar, rasanya tidak ada yang hilang, malah mendapat jauh lebih banyak
- Jika Anda merasakan kegembiraan saat mulai memakai HTMX, Anda akan merasakan lompatan serupa lagi di Datastar, seolah menemukan kembali apa yang memang seharusnya dilakukan web sejak awal
2 komentar
Datastar - framework hypermedia ringan untuk membangun aplikasi web interaktif
Opini Hacker News
hx-trigger="click"dihapus, atributnya langsung berkurang 20%. Dan menurut saya contoh itu akan lebih meyakinkan jika HTML-nya dibuat lebih aksesibel, misalnya memakai<button>alih-alih<span>. Pada akhirnya, kekuatan Datastar tampaknya adalah ia hadir dengan kemampuan seperti Alpine atau Stimulus yang sudah tertanam, dan itu benar-benar mengesankandata-replace-urlyang otomatis memperbarui URL view saat ini ke koordinat tersebut (x=123&y=456, dll.)<span hx-target="#rebuild-bundle-status-button" hx-select="#rebuild-bundle-status-button" hx-swap="outerHTML" hx-trigger="click" hx-get="/rebuild/status-button"></span>tampaknya diubah menjadi kode datastar seperti ini:<span data-on-click="@get('/rebuild/status-button')"></span>Bahkan contoh-contoh lainnya lebih membingungkan. Pada akhirnya saya tetap tidak paham mengapa orang berpindah dari htmx ke Datastar/rebuild/status-button, lalu ekstrak elemen#rebuild-bundle-status-buttondari HTML yang dikembalikan, kemudian ganti elemen yang ada sekarang”. Sementara di Datastar artinya menjadi “saat span diklik, ikuti saja perintah dari/rebuild/status-button”. Jika server mengembalikan elemen dengan beberapa ID, Datastar akan otomatis mengenali semuanya dan menggantinya. Jadi tanpatarget,select, danswappun, asal diberi ID, perilakunya tetap sesuai maksudhtmx-swap-oob="true"wajib ada, kalau tidak perilakunya berbeda dari yang diharapkan 2. Sebaliknya, kalau bukan OOB laluhtmx-swap-oob="true"ada, atribut itu akan diabaikan atau malah menyebabkan perilaku salah. Akibatnya, ketika komponen yang sama ingin dipakai ulang sebagai OOB/non-OOB, server harus selalu mengirim flagisOob, dan itu sangat merepotkan