1 poin oleh GN⁺ 2025-05-20 | 1 komentar | Bagikan ke WhatsApp
  • Zod 4 dirilis sebagai versi stabil setelah satu tahun pengembangan, memperbaiki keterbatasan desain Zod 3 dan meningkatkan performa, ukuran bundle, serta efisiensi kompilasi TypeScript secara signifikan
  • Zod 3, yang dirilis pada Mei 2021, tumbuh dari 2.700 star GitHub dan 600 ribu unduhan mingguan menjadi 37,8k star dan 31 juta unduhan mingguan saat ini; setelah 24 versi minor, peningkatan besar mulai membutuhkan perubahan yang memutus kompatibilitas
  • Dalam benchmark, parsing string menjadi 14x lebih cepat, parsing array 7x lebih cepat, parsing objek 6,5x lebih cepat, dan instansiasi tipe tsc pada contoh sederhana turun dari lebih dari 25.000 kali menjadi sekitar 175 kali
  • Ukuran bundle inti berdasarkan gzip turun dari Zod 3 12.47kb menjadi Zod 4 versi reguler 5.36kb, sementara Zod Mini, API fungsional yang bisa di-tree-shaking, mengecil hingga 1.88kb
  • Fitur baru mencakup konversi JSON Schema, registry metadata, inferensi tipe objek rekursif, internasionalisasi, pretty-printing error, tipe template literal, z.stringbool(), parameter error terpadu, peningkatan z.discriminatedUnion(), dan lainnya

Mengapa Zod 4 menjadi versi mayor baru

  • Zod 4 menjadi versi stabil setelah satu tahun pengembangan aktif, menghadirkan fitur-fitur yang sudah lama diminta di atas fondasi yang lebih cepat, lebih kecil, dan lebih efisien untuk tsc
  • Zod v3.0 dirilis pada Mei 2021; saat itu memiliki 2.700 star GitHub dan 600 ribu unduhan mingguan
  • Saat ini Zod mencatat 37,8k star GitHub dan 31 juta unduhan mingguan
    • Enam minggu sebelum beta dirilis, unduhan mingguannya berada di angka 23 juta
  • Setelah 24 versi minor, codebase Zod 3 mencapai batasnya, dan fitur serta peningkatan yang paling banyak diminta membutuhkan perubahan yang memutus kompatibilitas
  • Zod 4 menutup 9 dari 10 issue publik dengan upvote terbanyak

Performa parsing dan efisiensi kompilasi TypeScript

  • Zod 4 menyediakan benchmark yang dapat dijalankan langsung dari repositorinya
  • Peningkatan performa parsing:
    • Parsing string: 14x lebih cepat
    • Parsing array: 7x lebih cepat
    • Parsing objek: 6,5x lebih cepat
  • Benchmark parsing objek menjalankan Moltar validation library benchmark
  • Berdasarkan tsc --extendedDiagnostics, instansiasi tipe saat mengompilasi file sederhana turun drastis
    • Saat memakai "zod/v3": lebih dari 25.000 kali
    • Saat memakai "zod/v4": sekitar 175 kali
  • Zod 4 mendesain ulang dan menyederhanakan generic pada ZodObject serta kelas skema lain untuk menghindari ledakan instansiasi
  • Pola merangkai .extend() dan .omit() berulang kali membutuhkan 4000ms untuk dikompilasi di Zod 3, dan pemanggilan .extend() tambahan dapat memicu error "Possibly infinite"
  • Pola yang sama dikompilasi dalam 400ms di Zod 4, menjadi 10x lebih cepat
  • Ke depannya, jika digunakan bersama compiler tsgo, performa editor Zod 4 dapat diskalakan ke skema dan codebase yang lebih besar

Ukuran bundle dan Zod Mini

  • Ukuran bundle inti dibandingkan dengan mem-bundle skrip validasi z.boolean() sederhana menggunakan rollup
  • Ukuran bundle inti berdasarkan gzip:
    • Zod 3: 12.47kb
    • Zod 4 versi reguler: 5.36kb
  • Bundle inti Zod 4 versi reguler sekitar 57% lebih kecil dari Zod 3, atau berkurang 2,3x
  • API Zod yang berpusat pada method pada dasarnya sulit di-tree-shaking, dan skrip z.boolean() sederhana pun ikut membawa implementasi method yang tidak digunakan seperti .optional() dan .array()
  • Zod Mini menyediakan API fungsional yang bisa di-tree-shaking dan berpadanan 1:1 dengan zod
    • Di tempat Zod memakai method, Zod Mini umumnya memakai fungsi wrapper
    • Method parsing sama antara Zod dan Zod Mini
    • Method serbaguna .check() digunakan untuk menambahkan refinement
  • Zod reguler tetap direkomendasikan untuk sebagian besar kasus penggunaan, sementara proyek dengan batasan ukuran bundle yang tidak biasa ketat dapat mempertimbangkan Zod Mini
  • Saat memakai zod/mini, ukuran bundle gzip adalah 1.88kb
    • Turun 85% atau 6,6x dibanding Zod 3
    • Tabel perbandingan: Zod 3 12.47kb, Zod 4 reguler 5.36kb, Zod 4 Mini 1.88kb
  • Detail selengkapnya tersedia di dokumentasi zod/mini

Metadata dan JSON Schema

  • Zod 4 memperkenalkan sistem baru untuk menambahkan metadata bertipe kuat ke skema
  • Metadata disimpan bukan di skema itu sendiri, melainkan di schema registry yang menghubungkan skema dengan typed metadata
  • Registry dapat dibuat dengan z.registry(), dan pendaftaran praktis juga bisa dilakukan lewat method .register() pada skema
  • Zod mengekspor registry global z.globalRegistry yang menerima metadata umum yang kompatibel dengan JSON Schema
  • Method .meta() memudahkan penambahan skema ke z.globalRegistry
  • Demi kompatibilitas Zod 3, .describe() tetap tersedia, tetapi di Zod 4 .meta() direkomendasikan
  • Zod 4 menyediakan konversi JSON Schema first-party melalui z.toJSONSchema()
  • Metadata dari z.globalRegistry otomatis disertakan dalam output JSON Schema
  • Informasi kustomisasi JSON Schema yang dihasilkan tersedia di dokumentasi JSON Schema

Ekspresi skema dan fitur tipe baru

  • Zod 4 dapat menginferensi tipe objek rekursif dengan benar
    • Dapat mengekspresikan tipe rekursif dan tipe rekursif bersama
    • Tidak memerlukan type casting, berbeda dari pola tipe rekursif di Zod 3
    • Skema hasilnya adalah instance ZodObject biasa dan dapat memakai seluruh method
  • File schema ditambahkan untuk validasi instance File
  • z.templateLiteral() mengekspresikan tipe template literal TypeScript
    • Tipe skema Zod yang dapat diubah menjadi string menyimpan regex internal
    • Targetnya mencakup string, format string seperti z.email(), number, boolean, bigint, enum, literal, undefined/optional, null/nullable, dan template literal lain
    • Konstruktor z.templateLiteral menggabungkannya menjadi satu super-regex
    • Format string seperti z.email() ditegakkan dengan benar, tetapi custom refinement tidak ditegakkan
    • Detail selengkapnya tersedia di dokumentasi template literal
  • Format angka baru ditambahkan untuk mengekspresikan integer lebar tetap dan tipe floating-point
    • Mengembalikan instance ZodNumber yang sudah memiliki constraint inclusive minimum/maximum yang sesuai
  • Format angka bigint yang melampaui rentang yang dapat direpresentasikan secara aman oleh JavaScript number juga ditambahkan
    • Mengembalikan instance ZodBigInt yang sudah memiliki constraint inclusive minimum/maximum yang sesuai
  • z.literal() kini dapat menerima beberapa nilai secara opsional

Error, internasionalisasi, dan format string

  • Zod 4 memperkenalkan API locales baru untuk menerjemahkan pesan error secara global ke berbagai bahasa
  • Daftar lengkap locale yang didukung tersedia di Customizing errors dan diperbarui saat dukungan bahasa ditambahkan
  • Zod mengimplementasikan fungsi tingkat atas z.prettifyError yang mengubah ZodError menjadi string berformat ramah pengguna
    • Format saat ini belum dapat dikonfigurasi
    • Dapat berubah di masa mendatang
    • Jika sudah memakai zod-validation-error, Anda dapat tetap menggunakannya
  • Semua format string seperti email dipromosikan menjadi fungsi tingkat atas pada modul z
    • Lebih ringkas dan lebih ramah tree-shaking
    • API method padanan seperti z.string().email() tetap dapat digunakan, tetapi berstatus deprecated
    • Direncanakan dihapus pada versi mayor berikutnya
  • API z.email() mendukung custom regular expression
    • Tidak ada satu canonical email regex yang baku, dan tiap aplikasi dapat memilih kriteria yang lebih ketat atau lebih longgar
    • Zod mengekspor beberapa regex umum demi kemudahan

Konversi boolean dan penyederhanaan kustomisasi error

  • z.coerce.boolean() yang sudah ada adalah API sederhana yang mengubah nilai falsy menjadi false dan nilai truthy menjadi true
    • false, undefined, null, 0, "", NaN, dan sejenisnya menjadi false
    • Perilaku ini sesuai dengan API z.coerce lainnya
  • Zod 4 memperkenalkan z.stringbool() untuk boolean coercion ala env yang lebih canggih
  • Sebagian besar perubahan yang memutus kompatibilitas di Zod 4 terkait dengan API kustomisasi error
  • Kustomisasi error disatukan ke dalam satu parameter error
    • message digantikan oleh error
    • Parameter message tetap didukung, tetapi berstatus deprecated
    • invalid_type_error dan required_error digantikan oleh error dengan sintaks fungsi
    • errorMap juga digantikan oleh error dengan sintaks fungsi

Komposabilitas, refinement, dan transformasi

  • z.discriminatedUnion() mendukung beberapa tipe skema yang sebelumnya tidak didukung
    • Termasuk union dan pipe
    • Discriminated union dapat digunakan sebagai anggota discriminated union lain, sehingga menjadi komposable
  • Di Zod 3, refinement disimpan dalam kelas ZodEffects yang membungkus skema asli
    • Struktur ini membuat .refine() tidak nyaman dicampur dengan method skema lain seperti .min()
  • Di Zod 4, refinement disimpan di dalam skema, sehingga .refine() dapat digunakan bersama method skema lain secara alami
  • Method baru .overwrite() mengekspresikan transform yang tidak mengubah inferred type
    • .transform() adalah black box: tipe output-nya tidak bisa diintrospeksi saat runtime, dan fungsi transform dapat mengembalikan apa pun
    • Karena itu tidak ada cara aman untuk mengonversinya ke JSON Schema
    • .overwrite() mengembalikan instance dari kelas asli
    • Fungsi overwrite disimpan sebagai refinement dan tidak mengubah inferred type
  • .trim(), .toLowerCase(), dan .toUpperCase() yang sudah ada diimplementasikan ulang menggunakan .overwrite()

Fondasi untuk penulis library

  • Dengan penambahan Zod Mini, dibuat subpaket zod/v4/core yang memuat fungsi inti yang dipakai bersama oleh Zod dan Zod Mini
  • zod/v4/core memperluas Zod dari library sederhana menjadi fondasi validasi cepat yang dapat disematkan ke library lain
  • Jika membuat library skema, Anda dapat merujuk implementasi Zod dan Zod Mini untuk membangun di atas zod/v4/core
  • Untuk penulis library, tersedia panduan For library authors
    • Membahas best practice saat membangun di atas Zod
    • Menjawab pertanyaan umum tentang cara mendukung Zod 3, Zod 4, dan Mini secara bersamaan

1 komentar

 
GN⁺ 2025-05-20
Komentar Hacker News
  • Saya penulisnya, silakan tanya apa saja. Untuk kebijakan versi, saya sudah merangkum alasan pendekatan ini dengan cukup rinci: https://github.com/colinhacks/zod/issues/4371
    Pada akhirnya npm memang tidak dirancang untuk menangani situasi yang dihadapi Zod dengan baik. Puluhan hingga ratusan library mengimpor langsung interface/class Zod dan memakainya dalam API publik mereka sendiri, sehingga setiap kali Zod menaikkan versi mayor, library-library itu juga harus merilis versi mayor baru
    Jika dilihat secara terpisah, itu masuk akal, tetapi di Zod bisa terjadi longsoran versi yang menyakitkan bagi semua orang, dan sepertinya sebagian besar ekosistem akan terkunci di v3 selamanya
    Jadi, mirip dengan cara Go, kami memilih menambahkan subpath baru alih-alih paket merilis versi baru yang memutus kompatibilitas. Di ekosistem TypeScript, library bisa hanya memiliki satu peer dependency zod@^3.25.0 dan mendukung dua versi sekaligus dengan mengimpor yang diperlukan dari "zod/v3" dan "zod/v4"

    • Peningkatan performa tsc di codebase besar sangat menggembirakan, dan perubahan pada discriminated union juga tampaknya akan sangat membantu skenario tertentu yang selama ini kurang terlayani
      Namun meski saya memahami mengapa kebijakan versi yang agak aneh ini dipilih karena keadaan khusus, dari sudut pandang tim yang tidak perlu mengkhawatirkan konflik versi Zod pada dependensi transitif, saya berharap ada juga paket 4.0.0
      Kalau pemahaman saya benar, import harus diubah menjadi "zod/v4", dan ini perubahan yang sangat berisik; selain itu bisa merepotkan karena masalah auto-import IDE dari 'zod' harus ditangkap dengan aturan lint
    • Cara ini sangat masuk akal. Artinya pembaruan keamanan untuk versi lama juga bisa disediakan bersama dalam rilis codebase yang sama
    • Saya sedang di ponsel jadi tidak sempat melihat apakah ini sudah ada di tulisan, tetapi saya penasaran apakah perbaikan .optional() di TypeScript termasuk dalam penyelesaian 9–10 isu teratas: https://github.com/colinhacks/zod/issues/635
      Ini adalah rasa sakit terbesar saya di Zod, tetapi Zod tetap sangat bagus sehingga saya menerimanya dan terus memakainya
    • Berkat fitur baru, sepertinya saya bisa menghapus banyak hack sementara yang saya buat secara lokal. Saya memakai versi sendiri dari https://github.com/raflymln/zod-key-parser untuk menghindari typo pada nama form, dan saya agak terkejut fitur seperti ini belum masuk langsung ke library
      Saya penasaran apakah ini dianggap di luar cakupan Zod, atau hanya belum sempat diimplementasikan. Diskusi terkait ada di https://github.com/colinhacks/zod/discussions/2134
    • Jika maksudnya versi paling awal Zod 4 adalah 3.25.0, ini terdengar agak tidak masuk akal
      Saya sudah memakai versi alfa Zod selama beberapa bulan dan ingin cukup memperbaiki package.json untuk upgrade, tetapi sekarang rasanya saya harus menelusuri seluruh histori git
      Saya sangat berterima kasih atas proyek ini, tetapi untuk umpan balik yang satu ini, rasanya dibuat lebih sulit dari yang perlu. Sepertinya 4.x juga bisa saja dipublikasikan bersama 3.x
  • Pernyataan bahwa “untuk menyederhanakan migrasi, Zod 4 didistribusikan bersama Zod 3 sebagai bagian dari rilis zod@3.25, dan diimpor dari subpath "/v4"” tampak seperti sinyal bahwa manajemen dependensi npm benar-benar berantakan
    Peer dependency sudah begitu rusak sampai v4 harus berpura-pura sebagai v3

    • Saya penulisnya. Alasan pendekatan ini saya tulis cukup rinci di sini: https://github.com/colinhacks/zod/issues/4371
      Memang benar npm tidak mengelola situasi yang dihadapi Zod dengan baik. Namun Zod dibatasi oleh fakta bahwa hampir tidak ada library yang menerima sembarang versi. Puluhan hingga ratusan library mengimpor langsung interface/class dari "zod" dan menggunakannya dalam API publik mereka
      Library seperti ini harus merilis versi mayor baru setiap kali Zod menaikkan versi mayor, dan di Zod hal itu bisa memicu longsoran versi yang menyakitkan bagi semua orang. Jujur saja, rasanya sebagian besar ekosistem akan terkunci di v3 selamanya
      Jadi, mirip dengan Go, kami memilih menambahkan subpath baru alih-alih menerbitkan versi paket baru untuk setiap rilis yang memutus kompatibilitas. Di ekosistem TypeScript, satu peer dependency zod@^3.25.0 bisa mendukung "zod/v3" dan "zod/v4" sekaligus
    • Kesimpulan bahwa “peer dependency rusak sehingga v4 berpura-pura sebagai v3” tampaknya tidak tepat. Menurut saya Zod v4 dimasukkan ke dalam v3 agar pengguna bisa berpindah secara bertahap
      Dengan kata lain, alurnya adalah melakukan refactor penggunaan satu per satu menjadi import ... from 'zod/v4', lalu setelah selesai naik sepenuhnya ke v4
    • Rasanya komentar negatif apa pun akan mendapat upvote. Keputusan ini lebih merupakan cara praktis untuk memungkinkan library dengan banyak perubahan yang memutus kompatibilitas bermigrasi secara bertahap, bukan batasan mendasar dari npm itu sendiri
    • Mungkin pandangan saya menyempit karena selama bertahun-tahun hanya memakai npm, tetapi saya penasaran apa cara yang lebih baik untuk melakukan migrasi secara iteratif dari v3 ke v4, alih-alih pindah besar-besaran sekaligus
    • Ini bukan masalah npm saja. Masalah ketika suatu dependensi bergantung pada versi lama melalui dependensi transitif lain pada dasarnya muncul di semua ekosistem
      Justru npm punya lebih banyak jalan keluar karena jika perlu bisa menjalankan beberapa versi sekaligus atau secara selektif menimpa sebagian graf dependensi transitif
      Sistem manajemen paket mana yang menyelesaikan masalah ini? Platform “stabil” seperti Maven pun menangani masalah seperti ini dengan merilis versi di namespace baru, seperti ketika Apache Commons berpindah dari v2 ke v3
  • Ada pertanyaan yang sudah lama membuat saya penasaran. Saya pernah mendengar Zod bisa cocok untuk ini, tetapi setelah melihat dokumentasinya pun saya masih tidak yakin harus melakukannya bagaimana
    Misalkan API server mengembalikan tipe yang lebih canggih daripada yang bisa diekspresikan olehnya. Misalnya api/:postid/author mengembalikan User, tetapi bisa berupa User biasa atau User anonim, sehingga field seperti username, location bisa datang sebagai null. Dalam kasus ini, kita mungkin ingin merepresentasikan objek User sebagai discriminated union
    Objek dari endpoint lain juga mungkin memerlukan konversi tipe. User kadang menyertakan Post[], dan jika Post adalah tulisan moderator, ia juga bisa memiliki properti khusus
    Dulu saya menulis fungsi seperti normalizeUser() dan normalizePost(), tetapi cepat sekali menjadi berantakan. Karena tiap endpoint mengembalikan subset berbeda dari model User/Post, saya akhirnya membuat sekitar 5 normalizePost, dan itu terlalu kacau. Saya penasaran biasanya masalah seperti ini diselesaikan bagaimana

    • Sepertinya bisa memakai discriminated union
      Caranya memisahkan objek success dan failed berdasarkan field pembeda seperti status. Jika ada banyak properti khusus untuk moderator tetapi tidak ingin mencantumkan atau memeriksa semuanya, Anda bisa mendefinisikan perilaku passthrough
      Meski beberapa metode memiliki skema berbeda, jika ada bagian umum, buat skema objek bersama, lalu buat objek-objek yang menambahkan field di atasnya. Jika kemungkinannya banyak, tetap saja bisa berantakan, tetapi jika situasinya memang sudah berantakan, validator setidaknya bisa memvalidasi kekacauan itu
    • Idealnya harus ada single source of truth tentang bentuk apa saja yang bisa dimiliki User. Ini bisa berupa discriminated union seperti User dan AnonymousUser
      Jika bukan full-stack TypeScript, misalnya pada backend Python, berbagai bentuk User bisa didefinisikan sebagai model dan union Pydantic, lalu tipe client TypeScript dibuat lewat pembuatan skema OpenAPI/GraphQL dan code generation
    • Perlu tahu lebih banyak tentang use case-nya untuk menyelesaikannya, tetapi jika menambahkan properti pembeda seperti "user_type" ke semua tipe di dalam union, kasus umum dan kasus khusus menjadi lebih mudah ditangani
      Misalnya, jika memeriksa user.user_type === 'authenticated', sistem tipe akan tahu bahwa setelah itu user.name bisa digunakan
    • Ini tidak langsung membantu untuk kasus sekarang, tetapi GraphQL memang dibuat untuk hal seperti ini
      Library TypeScript untuk query GraphQL bisa secara dinamis menginfer bentuk respons dari bentuk field yang dipilih. Jika memilih { user { username posts { text } } }, tipe respons akan memiliki posts, dan jika hanya memilih { user { username } }, properti posts akan benar-benar tidak ada
    • Server harus mengekspor tipe. Menulis tipe secara manual di client itu tidak masuk akal
      Server tahu data apa yang dikirimnya, jadi informasi itu harus disediakan ke client sebagai metadata. Secara praktis, backend Python bisa memakai skema Pydantic, otomatis menghasilkan spesifikasi OpenAPI berdasarkan itu, lalu client menghasilkan tipe darinya
  • Zod jauh lebih baik daripada alternatif yang pernah saya lihat, tetapi fakta bahwa validasi eksplisit seperti ini diperlukan kadang terasa seperti kegagalan tentang ke mana pengembangan web modern telah sampai
    Dalam pengembangan full-stack, sangat menjengkelkan harus mendeskripsikan bentuk yang sama dengan banyak cara. Jadi diperlukan validasi input JS, Swagger untuk definisi API, validasi input sisi server, ORM untuk kepatuhan skema, hingga definisi TypeScript terpisah di server dan client; semuanya membosankan

    • Sikap TypeScript yang bersikeras menjadi sistem khusus pemeriksaan statis/compile-time adalah luka yang disayangkan bagi seluruh ekosistem. Saya tidak berharap TypeScript menjadi runtime checker, tetapi saya berharap ia mengekspor data tipe yang bisa digunakan secara berguna untuk class, function, dan object
      TypeScript terasa seperti single source of truth terbaik yang kita punya, tetapi pada praktiknya alat-alat yang mencoba melakukan reflection masing-masing mendefinisikan ulang model dan builder mereka sendiri. Ada 5 area besar yang menjadikan reflection sebagai inti, dan masing-masing punya banyak implementasi
      Tool lama untuk emisi tipe TypeScript, reflect-metadata, menyediakan sebagian informasi tipe runtime, tetapi menargetkan spesifikasi decorator dan metadata yang sangat lama: https://www.npmjs.com/package/reflect-metadata
      Mungkin kita sedang berada di awal konsolidasi. Proyek Standard Schema tampaknya didukung oleh sebagian besar library validasi utama. Namun memperluasnya sampai ke definisi API atau tool ORM masih sangat awal
      https://github.com/standard-schema/standard-schema?tab=readm...
    • Sebenarnya itulah inti dari tool seperti ini. Definisikan sekali saja, lalu hasilkan semua yang di bawahnya secara dinamis
      Jika mengubah satu hal di skema Zod, perubahan itu menyebar ke seluruh aplikasi bersama type checking. Skema Zod menjadi single source of truth
    • Biasanya tidak perlu mendefinisikan ulang data di sana-sini. Ada sangat banyak tool untuk mengonversi ke Zod atau dari Zod
      Jika sudah memiliki skema JSON Schema/Swagger, buat saja Zod darinya. Jika memakai ORM TypeScript, hampir pasti ada generator Zod
      Jujur, karena Zod begitu luas dipakai, bagi saya ia menjadi definisi skema terpadu yang bisa diandalkan oleh bagian lain dalam stack. Karena tipe didefinisikan langsung, developer benar-benar menjaganya tetap mutakhir. Dokumentasi Swagger perusahaan selalu tertinggal dari perubahan
    • Semua API bersifat eksperimental dan terus berubah serta berevolusi; web juga begitu
      Status quo hanya baik-baik saja ketika berhadapan dengan client dan pemberi kerja yang hanya menginginkan hasil dan tidak peduli caranya. Dalam konteks seperti itu, lapisan-lapisan kompleksitas yang menyedihkan ini setidaknya menambah jam kerja yang bisa ditagihkan
    • Banyak orang yang mengeluh bahwa pengembangan web modern itu kompleks, sepertinya juga akan tidak suka pada usulan untuk mengganti semua ini hanya dengan TypeScript dan Zod
      Tentu saja dengan asumsi Zod adalah library definisi skema dan validasi TypeScript pilihan mereka
  • Zod 4 terlihat bagus, tetapi meski menyertakan peningkatan terbaru, ArkType masih beberapa kali lebih cepat dalam kisaran satu digit
    Demi kompatibilitas mundur dan kompatibilitas sintaks, kadang sulit membuatnya jauh lebih cepat seperti library yang benar-benar dimulai dari nol. Di proyek terbaru, saya menganalisis semua alat seperti ini, dan sebagian karena alasan tersebut memilih ArkType. Pengalaman memakai TypeScript juga terasa lebih baik

    • Saya melihat metrik kecepatannya, dan penasaran apakah ada yang bisa menjelaskan di mana kecepatan itu membuat perbedaan
      Kami memakai Zod hanya untuk validasi form, jadi saya berpikir, “kenapa ini penting?” Mungkin ada orang yang memvalidasi sesuatu seperti pesan input API dengan throughput tinggi sehingga performa menjadi lebih penting
    • Penasaran kenapa memilih ArkType dibanding TypeBox
    • Menariknya, saat melakukan riset saya bahkan tidak melihat alat itu. Saya juga terutama memperhatikan pengalaman TypeScript-nya
      Meski begitu, rasanya saya tidak akan pindah dari Zod
    • ArkType adalah mimpi buruk untuk ditulis, sedangkan Zod enak ditulis
  • Selamat kepada tim Zod atas rilis barunya. Walau berisiko terdengar terlalu negatif, saya bergidik melihat jumlah breaking changes yang tercantum di panduan migrasi
    Untuk proyek yang sangat bergantung pada Zod, ini sepertinya akan menjadi pekerjaan berat yang membutuhkan banyak fokus dan waktu developer. Saya makin merasakannya karena pernah memelihara beberapa proyek frontend berusia 4–5 tahun di tempat kerja
    Proyek React besar biasanya bergantung pada banyak library, dan ketika tiap library mengeluarkan perubahan besar, apalagi dokumentasinya kurang, semuanya bisa cepat terasa kewalahan. Ini salah satu bagian yang paling saya benci saat bekerja dengan JavaScript, dan menjaga semuanya tetap selaras agar terus berjalan mulus terasa seperti tanjakan tanpa akhir

    • Sangat setuju. Saya mengoperasikan beberapa aplikasi Next.js besar, dan selama setahun terakhir harus melewati perubahan cache besar-besaran Next.js 14 → 15, Next.js pages → app router, React 18 → 19, Eslint 8 → 9, Tailwind 3 → 4
      Jujur itu seperti mimpi buruk, dan saya berpikir seandainya saja dibuat dengan Django. Di luar dugaan, migrasi Tailwind 3 → 4 termasuk yang paling menyakitkan
    • Karena itulah mereka memilih pendekatan distribusi ganda bersama edisi mini terpisah. Ini memudahkan migrasi bertahap tanpa mengutak-atik package manager
      Pengguna yang tidak tertarik pada edisi mini tidak perlu memedulikan bagian itu. Namun manfaat tree shaking dari edisi mini terlalu besar sampai mendorong pengembangan alternatif, dan Zod harus menerimanya atau meredup
    • Pakai LLM saja
  • Sebagai developer full-stack yang menjalankan sendiri SaaS dengan ribuan pengguna di produksi, saya kadang merasa senang menyadari betapa banyak masalah yang sama sekali tidak saya ketahui karena memutuskan untuk tidak membuat SPA dan tidak memakai framework frontend JS
    Saya bahkan tidak pernah terpikir membutuhkan sesuatu seperti Zod/ArkType, baru pertama kali mendengarnya, dan tidak punya alasan untuk memakainya
    Saya terkejut dengan banyaknya usaha, kompleksitas, dan tooling yang diperlukan untuk membuat SPA. Jika memutuskan untuk tidak membuat SPA, satu kelompok masalah tertentu langsung tidak ada. Sebagai gantinya, browser dipakai sebagaimana awalnya dirancang, dengan refresh halaman penuh dan fokus pada pengembangan backend, lalu sesekali menambahkan reaktivitas dengan framework khusus backend seperti Laravel Livewire
    Semuanya sederhana, mulai dari kontrol akses, validasi, hingga manajemen state. Aplikasinya cepat, responsif, modern, ramah SEO, dan melayani ribuan orang di produksi

    • Di dua proyek besar dengan lebih dari 5 tim yang bekerja bersama, kami memakai Zod dan Protobuf agar evolusi skema berjalan baik. Bahkan untuk frontend ringan, masuk akal memakai sesuatu di backend untuk memvalidasi skema
      Pada akhirnya, skema itu ada di suatu tempat. Bisa didefinisikan di sistem database, bisa juga di model ORM. Namun pada proyek besar, menaruh skema di sistem database atau ORM bisa menimbulkan masalah yang sangat sulit, jadi kami memakai Zod dan Protobuf. Menurut saya Protobuf juga bisa sepenuhnya digantikan oleh Zod atau yang serupa
      Skandal British Post Office melibatkan sistem IT bernama Horizon: https://en.wikipedia.org/wiki/British_Post_Office_scandal
      Setelah membaca detailnya, saya rasa validasi skema seperti Zod bisa berkontribusi mencegah skandal ini. Lampiran teknis dokumen pengadilan class action juga menyebutkan ketiadaan penggunaan skema: https://en.wikipedia.org/wiki/Bates_%26_Others_v_Post_Office...
    • Zod tidak ada hubungannya dengan SPA dan bukan alat khusus frontend. Apakah Anda tidak melakukan validasi input di kode?
    • Kadang kalau menutup mata, satu kelompok masalah memang jadi tidak ada
    • Penasaran bagaimana Anda melakukan validasi sisi server
      Dari ceritanya, terdengar seperti sekarang Anda menulis banyak pernyataan if secara defensif. Lebih buruk lagi, bisa jadi hanya mengandalkan validasi form sisi klien HTML
    • Kami punya sangat banyak skema Zod khusus backend yang dipakai sebagai bagian dari pipeline data. Jadi bagi saya alat ini tidak terlihat seperti hanya ada untuk menyelesaikan masalah SPA
  • Saya bukan ahli jadi harus berhati-hati, tetapi menurut saya JSON Schema bisa menjadi pilihan yang baik karena berbasis skema, sehingga validator dapat diimplementasikan juga dalam bahasa selain TypeScript
    https://ajv.js.org adalah salah satu pustaka JSON Schema seperti itu. Saya penasaran bagaimana perbandingannya dengan Zod

    • Zod bukan alat yang hanya untuk validasi JSON. Ia dapat memvalidasi objek yang tidak bisa direpresentasikan sebagai JSON tanpa transformasi, misalnya tanggal atau instance class
      Jika mau, ia juga bisa dipakai sebagai konverter JSON. Misalnya, Anda bisa menulis skema yang menerima string, memvalidasi apakah itu string tanggal ISO, lalu menghasilkan objek Date
    • Zod 4 mendukung secara native fitur untuk mengonversi skema Zod menjadi JSON Schema. Dulu ini juga sudah bisa dilakukan dengan pustaka pihak ketiga
      Perbedaan pentingnya adalah preprocessing dan refine. Di Zod, Anda bisa menyediakan callback sebelum validasi, dan ini sangat berguna tetapi tidak bisa direpresentasikan dalam JSON. Misalnya, mengubah MM/DD/YYYY menjadi DD/MM/YYYY sebelum validasi tanggal ternyata lebih sering berguna daripada yang dikira
    • Dalam kasus seperti itu, JSON Schema adalah pilihan yang baik, dan TypeBox adalah cara yang cukup bagus untuk membuatnya
      Untuk validasi, Anda bisa memakai AJV atau sistem validasi skema milik TypeBox sendiri. Yang terakhir jauh lebih cepat tetapi hanya mendukung sinkron, sedangkan AJV punya opsi validasi asinkron seperti pengecekan database
    • Untuk validasi lintas bahasa, JSON Schema memang tepat. Jika membungkusnya dengan OpenAPI, Anda juga mendapat dokumentasi API yang cukup baik secara gratis
  • Saya terkejut dengan reaksi negatif di sekitar topik ini
    Saya menguji versi awal Zod v4 dan menyukai API barunya, tetapi sangat khawatir soal seperti apa jalur migrasinya nanti. Saya bahkan sempat berpikir untuk mengusulkan agar dirilis dengan nama paket yang benar-benar baru
    Namun pendekatan penulisnya cerdas. Ini memungkinkan orang seperti saya untuk langsung mengadopsi v4 tanpa harus menunggu semua dependensi diperbarui

    • Ini jalur yang bagus. Untuk hal seperti validasi, tidak ada cara untuk menanggung migrasi yang serba semua-atau-tidak-sama-sekali
  • Saya baru saja mulai mengadopsi Zod di proyek baru, dan waktunya tidak bisa lebih tepat dari ini
    Berdasarkan apa yang terlihat sekarang, sepertinya akan ada sangat banyak hal yang harus diubah untuk pindah ke v4