💎 Zod 4 is now stable!  Read the announcement.
Zod logo

Zod Mini

注意 — Zod Mini のドキュメントは、タブ付きのコードブロックを通じて通常の Zod のドキュメントと混在しています。このページは、Zod Mini が存在する理由、いつ使用するか、および通常の Zod とのいくつかの重要な違いを説明するために設計されています。

Zod Mini バリアントは、Zod 4 のリリースとともに導入されました。試すには:

npm install zod@^4.0.0

インポートするには:

import * as z from "zod/mini";

Zod Mini は zod とまったく同じ機能を実装していますが、関数型ツリーシェイク可能 な API を使用しています。zod から移行する場合、これは通常、メソッドの代わりに 関数 を使用することを意味します。

// 通常の Zod
const mySchema = z.string().optional().nullable();
 
// Zod Mini
const mySchema = z.nullable(z.optional(z.string()));

ツリーシェイキング (Tree-shaking)

ツリーシェイキングは、最終的なバンドルから未使用のコードを削除するために最新のバンドラーで使用される技術です。デッドコード削除 とも呼ばれます。

通常の Zod では、スキーマは一般的な操作(例:文字列スキーマの .min())を実行するためのさまざまな便利なメソッドを提供します。バンドラーは通常、バンドルから未使用のメソッド実装を削除(「ツリーシェイク」)することはできませんが、未使用のトップレベル関数を削除することはできます。そのため、Zod Mini の API はメソッドよりも多くの関数を使用します。

// 通常の Zod
z.string().min(5).max(10).trim()
 
// Zod Mini
z.string().check(z.minLength(5), z.maxLength(10), z.trim());

バンドルサイズの削減に関する一般的なアイデアを提供するために、次の単純なスクリプトを検討してください。

z.boolean().parse(true)

これを Zod と Zod Mini でバンドルすると、次のバンドルサイズになります。Zod Mini では 64% 削減されます。

パッケージバンドルサイズ (gzip)
Zod Mini2.12kb
Zod5.91kb

オブジェクト型を含むわずかに複雑なスキーマを使用した場合:

const schema = z.object({ a: z.string(), b: z.number(), c: z.boolean() });
 
schema.parse({
  a: "asdf",
  b: 123,
  c: true,
});
パッケージバンドルサイズ (gzip)
Zod Mini4.0kb
Zod13.1kb

これにより、関係するバンドルサイズの感覚がつかめるはずです。これらの数値をよく見て、独自のベンチマークを実行し、Zod Mini を使用する価値がユースケースにあるかどうかを判断してください。

いつ Zod Mini を使用する(しない)か

一般的に、バンドルサイズに関して特に厳しい制約がない限り、おそらく通常の Zod を使用すべきです。多くの開発者は、アプリケーションのパフォーマンスに対するバンドルサイズの重要性を過大評価しています。実際には、Zod の規模(通常 5-10kb)のバンドルサイズは、地方や発展途上国の低速なモバイルネットワーク接続を持つユーザーベース向けにフロントエンドバンドルを最適化する場合にのみ意味のある懸念事項です。

いくつかの考慮事項を見てみましょう。

DX (開発者体験)

Zod Mini の API はより冗長で、発見しにくいです。Zod の API のメソッドは、Zod Mini のトップレベル関数よりも、Intellisense を通じてはるかに簡単に発見でき、オートコンプリートも容易です。チェーンされた API でスキーマをすばやく構築することはできません。(Zod の作成者として言えば:私は Zod Mini API を可能な限り人間工学に基づいたものにするために多くの時間を費やしましたが、それでも標準の Zod API を強く好みます。)

バックエンド開発

バックエンドで Zod を使用している場合、Zod の規模のバンドルサイズは意味がありません。これは、Lambda のようなリソースに制約のある環境でも当てはまります。この投稿 は、さまざまなサイズのバンドルでのコールドスタート時間をベンチマークしています。以下は結果の一部です。

バンドルサイズLambda コールドスタート時間
1kb171ms
17kb (非 Mini Zod の gzip サイズ)171.6ms (補間値)
128kb176ms
256kb182ms
512kb279ms
1mb557ms

無視できるほどの 1kb バンドルの最小コールドスタート時間は 171ms です。テストされた次のバンドルサイズは 128kb で、これはわずか 5ms 追加されただけです。gzip 圧縮すると、通常の Zod 全体のバンドルサイズはおよそ 17kb であり、これは起動時間の 0.6ms の増加に相当します。

インターネット速度

一般的に、サーバーへのラウンドトリップ時間 (100-200ms) は、追加の 10kb をダウンロードするのに必要な時間をはるかに上回ります。低速な 3G 接続(1Mbps 未満)でのみ、追加の 10kb のダウンロード時間はより重要になります。地方や発展途上国のユーザー向けに特別に最適化していない場合は、他の何かを最適化することに時間を費やす方がおそらく良いでしょう。

ZodMiniType

すべての Zod Mini スキーマは z.ZodMiniType 基底クラスを継承しており、これはさらに zod/v4/corez.core.$ZodType を継承しています。このクラスは zodZodType よりもはるかに少ないメソッドを実装していますが、いくつかの特に便利なメソッドは残っています。

.parse

これは明らかです。すべての Zod Mini スキーマは、zod と同じ解析メソッドを実装しています。

import * as z from "zod/mini"
 
const mySchema = z.string();
 
mySchema.parse('asdf')
await mySchema.parseAsync('asdf')
mySchema.safeParse('asdf')
await mySchema.safeParseAsync('asdf')

.check()

通常の Zod には、一般的なチェックを実行するための専用のメソッドがスキーマサブクラスにあります。

import * as z from "zod";
 
z.string()
  .min(5)
  .max(10)
  .refine(val => val.includes("@"))
  .trim()

Zod Mini では、そのようなメソッドは実装されていません。代わりに、これらのチェックを .check() メソッドを使用してスキーマに渡します。

import * as z from "zod/mini"
 
z.string().check(
  z.minLength(5), 
  z.maxLength(10),
  z.refine(val => val.includes("@")),
  z.trim()
);

以下のチェックが実装されています。これらのチェックの一部は、特定のタイプのスキーマ(例:文字列や数値)にのみ適用されます。API はすべて型安全です。TypeScript は、サポートされていないチェックをスキーマに追加することを許可しません。

z.lt(value);
z.lte(value); // エイリアス: z.maximum()
z.gt(value);
z.gte(value); // エイリアス: z.minimum()
z.positive();
z.negative();
z.nonpositive();
z.nonnegative();
z.multipleOf(value);
z.maxSize(value);
z.minSize(value);
z.size(value);
z.maxLength(value);
z.minLength(value);
z.length(value);
z.regex(regex);
z.lowercase();
z.uppercase();
z.includes(value);
z.startsWith(value);
z.endsWith(value);
z.property(key, schema);
z.mime(value);
 
// カスタムチェック
z.refine()
z.check()   // .superRefine() を置き換えます
 
// 変更(これらは推論される型を変更しません)
z.overwrite(value => newValue);
z.normalize();
z.trim();
z.toLowerCase();
z.toUpperCase();

.register()

レジストリにスキーマを 登録 するため。

const myReg = z.registry<{title: string}>();
 
z.string().register(myReg, { title: "My cool string schema" });

.brand()

スキーマを ブランド化 するため。詳細については、ブランド化された型 のドキュメントを参照してください。

import * as z from "zod/mini"
 
const USD = z.string().brand("USD");

.clone(def)

提供された def を使用して、現在のスキーマの同一のクローンを返します。

const mySchema = z.string()
 
mySchema.clone(mySchema._zod.def);

デフォルトのロケールなし (No default locale)

通常の Zod は英語 (en) ロケールを自動的に読み込みますが、Zod Mini は読み込みません。これにより、エラーメッセージが不要な場合、英語以外の言語にローカライズされている場合、またはその他の方法でカスタマイズされている場合に、バンドルサイズが削減されます。

つまり、デフォルトでは、すべての問題の message プロパティは単に "Invalid input" と表示されます。英語ロケールを読み込むには:

import * as z from "zod/mini"
 
z.config(z.locales.en());

ローカリゼーションの詳細については、ロケール のドキュメントを参照してください。

On this page