Apa yang Berubah di Zod 4: Performa, Mini, dan Migrasi

Foto oleh Deutsches Spionagemuseum Berlin, CC BY-SA 4.0 via Wikimedia Commons (CC BY-SA 4.0)
Tidak. Zod 4 hadir di dalam paket zod utama — Anda menginstalnya dengan npm install zod pada versi 4. Build ringan yang baru adalah impor subpath, zod/mini, dari paket yang sama. Tidak ada paket @zod/four terpisah untuk diinstal.
Zod mempublikasikan benchmark parsing string sekitar 14x lebih cepat, array 7x lebih cepat, dan objek 6,5x lebih cepat dibanding Zod 3. Sama pentingnya, ia melaporkan pengurangan hingga 100x pada instansiasi tipe TypeScript saat merantai method seperti .extend() dan .omit(), yang mempercepat kompilasi dan responsivitas editor pada file skema besar.
Satu parameter error terpadu menggantikan required_error, invalid_type_error, dan errorMap. Anda memberikan error sebagai string untuk kasus sederhana, atau sebagai fungsi yang menerima issue dan bisa bercabang berdasarkan apakah input undefined. Field message lama masih bekerja tetapi sudah deprecated.
Gunakan zod/mini ketika ukuran bundle jadi kendala nyata: bundle browser, fungsi serverless dengan anggaran cold-start, dan runtime edge. Ukurannya sekitar 1,9 KB gzipped dan sepenuhnya tree-shakable. Di backend Node, tetaplah dengan Zod inti — ukuran bundle tak relevan di sana dan API method-chaining lebih mudah dibaca untuk dirawat.
Ya, ada codemod resmi bernama zod-v3-to-v4 yang menangani rename mekanis seperti migrasi parameter error dan memindahkan format string ke fungsi tingkat atas. Ia menangani sebagian besar pekerjaan, tetapi Anda tetap harus membaca setiap diff yang dihasilkannya, karena codemod andal pada perubahan rutin dan berisiko pada yang tak biasa.

Foto oleh Deutsches Spionagemuseum Berlin, CC BY-SA 4.0 via Wikimedia Commons (CC BY-SA 4.0)
Ringkasan Utama
Zod 4 hadir di dalam paket zod utama dan menulis ulang inti validasinya demi kecepatan: parsing string sekitar 14x lebih cepat, array 7x lebih cepat, dan pemangkasan 100x pada instansiasi TypeScript di skema berantai. Ia menambah build zod/mini yang tree-shakable sekitar 1,9 KB gzipped, menyatukan kustomisasi error di bawah satu parameter error, dan memindahkan format string ke fungsi tingkat atas seperti z.email().
Saya mengandalkan Zod di hampir setiap service TypeScript yang saya jalankan: memvalidasi request body di NestJS, mem-parse variabel environment saat boot, dan menjaga JSON yang saya tarik dari API pihak ketiga. Jadi ketika versi mayor rilis dengan sorotan berupa performa, saya menyimak. Zod 4 bukan sekadar pembaruan kosmetik. Intinya ditulis ulang, biaya di level tipe turun drastis, dan beberapa API yang saya pakai setiap hari berubah bentuk.
Berikut apa yang benar-benar berubah, berapa biaya migrasinya, dan di mana build zod/mini baru layak dipakai. Semua di bawah berasal dari pengalaman langsung meng-upgrade, disilangkan dengan catatan rilis resmi Zod 4 dan panduan migrasinya.
Angka runtime yang dipublikasikan Zod benar-benar besar: parsing string sekitar 14x lebih cepat, array 7x lebih cepat, dan objek 6,5x lebih cepat dibanding Zod 3. Itu berasal dari meratakan sistem check internal dan membunuh wrapper ZodEffects lama yang dulu membungkus refinement dan transform. Di jalur request panas yang memvalidasi setiap payload, itu berpengaruh.
Tetapi perubahan yang paling saya rasakan adalah yang di level tipe. Zod melaporkan pengurangan hingga 100x pada instansiasi tipe tsc ketika Anda merantai method seperti .extend() dan .omit(). Pada file skema besar, itulah perbedaan antara editor yang mengikuti dan editor yang tersendat. Jika Anda pernah melihat TypeScript tersendat pada skema Zod yang tersusun dalam. peningkatan ini saja sudah bisa membenarkan upgrade.
Sebelum migrasi, jalankan test suite Anda sekali di Zod 3 dan catat waktu jamnya. Ulangi setelah upgrade. Kemenangan runtime mudah terlihat di test yang berat parsing, dan memberi Anda angka konkret untuk ditaruh di deskripsi pull request alih-alih mengutip benchmark yang tidak Anda jalankan sendiri.
Ini perubahan breaking yang paling sering Anda temui. Zod 3 punya tiga cara tumpang tindih untuk mengustomisasi pesan: required_error, invalid_type_error, dan errorMap, ditambah message biasa pada refinement. Zod 4 meleburkan semuanya menjadi satu parameter error. Ia menerima string untuk kasus sederhana atau fungsi yang menerima issue untuk logika kondisional. Field message lama masih bekerja tetapi sudah deprecated.
// Zod 3 — three different knobs
const schema3 = z.string({
required_error: "Name is required",
invalid_type_error: "Name must be a string",
});
// Zod 4 — one unified `error`
const schema4 = z.string({
error: (issue) =>
issue.input === undefined
? "Name is required"
: "Name must be a string",
});
// Simple string form still works everywhere:
z.string().min(5, { error: "Too short" });Ada juga error map global sehingga Anda bisa melokalkan pesan di satu tempat, yang sangat berguna ketika Anda melayani pengguna berbahasa Inggris dan Indonesia. Model mentalnya lebih bersih: ada tepat satu tempat untuk mengatur error, dan itu sama di setiap posisi.
Di Zod 3 Anda menulis z.string().email(). Di Zod 4 validator format menjadi fungsi tingkat atas: z.email(), z.uuid(), z.url(), z.ipv4(), z.ipv6(). Bentuk method berantai masih ada tetapi deprecated, dan membawa biaya ukuran bundle karena memaksa seluruh mesin format string masuk ke build Anda. Fungsi tingkat atas bersifat tree-shakable, sehingga Anda hanya mengirim validator yang Anda impor.
// Deprecated (still works)
z.string().email();
z.string().uuid();
// Preferred in Zod 4
z.email();
z.uuid(); // stricter, RFC 9562
z.guid(); // looser GUID matching if you need it
z.url();z.uuid() lebih ketat di Zod 4 — ia memvalidasi terhadap RFC 9562 dan akan menolak beberapa string yang diterima Zod 3, termasuk nilai mirip UUID non-standar tertentu. Jika Anda memvalidasi ID dari sistem lama, uji dengan data nyata sebelum rilis, atau gunakan z.guid() untuk pencocokan yang lebih longgar.
Ada codemod resmi, zod-v3-to-v4, yang menangani rename mekanis seperti migrasi parameter error dan perpindahan format string. Saya tetap membaca setiap diff yang dihasilkannya — codemod hebat pada 90 persen yang membosankan dan berbahaya pada 10 persen yang menarik — tetapi ia benar-benar menghemat waktu saya di codebase besar.
Zod 4 memperkenalkan entry point kedua, zod/mini, dengan API fungsional yang sepenuhnya tree-shakable. Ukurannya sekitar 1,88 KB gzipped, kira-kira 85 persen lebih kecil dari build inti. Alih-alih merantai method, Anda mengomposisi fungsi, dan itulah yang membuatnya shake dengan baik: validator yang tak terpakai tak pernah sampai ke bundle Anda.
// Core Zod — method chaining
import * as z from "zod";
const User = z.object({
email: z.email(),
age: z.number().min(18),
});
// zod/mini — function composition, tree-shakable
import * as z from "zod/mini";
const UserMini = z.object({
email: z.email(),
age: z.number().check(z.minimum(18)),
});Saya tidak akan memakai zod/mini di backend. Di service Node ukuran bundle tak relevan dan ergonomi chaining Zod inti lebih enak dibaca dan dirawat. Tempat mini layak dipakai adalah edge: fungsi serverless dengan anggaran cold-start, bundle browser di mana setiap kilobyte adalah metrik nyata, dan runtime edge. API-nya berbagi inti yang sama, jadi Anda bisa pakai inti di server dan mini di klien tanpa belajar dua library validasi.
| Pertimbangan | Inti zod | zod/mini |
|---|---|---|
| Impor | import * as z from "zod" | import * as z from "zod/mini" |
| Bundle (gzipped) | Lebih besar, API chaining | ~1,9 KB, tree-shakable |
| Ergonomi | Method chaining, paling mudah dibaca | Komposisi fungsi |
| Paling cocok | Backend Node, server | Edge, serverless, browser |
Untuk sebagian besar proyek, migrasinya soal satu sore, bukan seminggu. Perubahan parameter error menyentuh banyak file tetapi bersifat mekanis, codemod mengerjakan sebagian besarnya, dan TypeScript menolak membiarkan Anda selesai selagi ada yang masih rusak. Hasilnya — parsing lebih cepat, type checking yang jauh lebih murah, dan build seukuran edge yang nyata — sepadan dengan diff-nya.