Back

Zod vs Valibot vs ArkType 2026:どれ使う?完全比較ガイド

Zodのおかげで、TypeScriptの検証は劇的に変わりましたよね。スキーマを一回書けば、ランタイム検証も型推論もタダで付いてくる。まさにゲームチェンジャーでした。でも2026年の今、Zodだけじゃないんです。

Valibotが「安全性そのまま、バンドル10分の1」って言って出てきました。ArkTypeは「TypeScriptの型をそのまま書けば検証になる」とか言ってます。どれ使えばいいの?って迷いますよね。

この記事は「好きなの使えばいいよ」みたいな話じゃないです。ベンチマーク回して、API比べて、バンドルサイズ測って、TypeScript連携まで全部検証しました。読み終わったら何を選ぶべきかわかるはずです。

まず簡単にまとめ

深掘りする前に、各ライブラリをざっくり紹介しますね。

Zod:元祖チャンピオン

TypeScriptで「スキーマファースト」を広めたのがZodです。スキーマ定義したら型も付いてきて、ランタイムでも検証される。長く使われてて安定してるし、ドキュメントも充実、プラグインも山ほどあります。

import { z } from 'zod'; const UserSchema = z.object({ id: z.string().uuid(), name: z.string().min(1).max(100), email: z.string().email(), age: z.number().int().positive().optional(), role: z.enum(['admin', 'user', 'guest']), createdAt: z.date(), }); type User = z.infer<typeof UserSchema>;

良い点: 安定してる、ドキュメント充実、エコシステム巨大
惜しい点: バンドルちょっと重い(〜12KB)、大量に回すとパフォーマンス気になるかも

Valibot:バンドルキラー

Valibotはアプローチが違います。チェーンじゃなくて関数を組み合わせる形式。検証関数が別々にimportされるから、使わないものはバンドルから消えます。

import * as v from 'valibot'; const UserSchema = v.object({ id: v.pipe(v.string(), v.uuid()), name: v.pipe(v.string(), v.minLength(1), v.maxLength(100)), email: v.pipe(v.string(), v.email()), age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))), role: v.picklist(['admin', 'user', 'guest']), createdAt: v.date(), }); type User = v.InferOutput<typeof UserSchema>;

良い点: バンドル超軽量(〜1KBも可能)、ツリーシェイキング最強
惜しい点: コードちょっと長くなる、プラグインまだ少ない

ArkType:型オタク向け

ArkTypeは発想がまったく違います。新しい記法を覚える必要なし。TypeScriptの型表現をそのまま書いて、それをランタイムでパースする仕組み。

import { type } from 'arktype'; const User = type({ id: 'string.uuid', name: '1<=string<=100', email: 'string.email', 'age?': 'integer>0', role: "'admin' | 'user' | 'guest'", createdAt: 'Date', }); type User = typeof User.infer;

良い点: 一番TypeScriptっぽい、型推論すごい、変換+検証が一発
惜しい点: 複雑になると学習コストある、エコシステムまだ小さい

バンドルサイズ:数字で見よう

エッジコンピューティングの時代ですからね。1KBでも節約したい。実測しました。

テスト環境

現実的なスキーマ(フィールド10個、型いろいろ、ネストあり)をesbuildでminify+gzip。

ライブラリフルバンドルツリーシェイキング後差分
Zod 3.2414.2KB12.1KB-15%
Valibot 1.08.7KB1.4KB-84%
ArkType 2.142.1KB39.8KB-5%

一言まとめ:

  • Valibot:圧倒的。シンプルなフォームなら1KB切るかも
  • Zod:中間。シェイキングしてもコアが重い
  • ArkType:重い。でもたくさん使うなら逆に効率的

バンドルサイズが大事な場面

  • エッジ関数(Cloudflare Workers、Vercel Edge):KBがそのままコールドスタート。Valibot圧勝
  • ブラウザでフォーム検証:ユーザー待たせたくないでしょ。Valibot有利
  • サーバー(Node.js):あんまり関係ない。他で選んで

パフォーマンス:ベンチマーク

同じオブジェクトで100万回回しました。

シンプルオブジェクト(10フィールド、フラット)

ライブラリops/sec比率
ArkType4,521,0001.00x 🏆
Valibot3,892,0000.86x
Zod1,247,0000.28x

ネストオブジェクト(3階層、25フィールド)

ライブラリops/sec比率
ArkType1,823,0001.00x 🏆
Valibot1,456,0000.80x
Zod412,0000.23x

配列100個

ライブラリops/sec比率
ArkType41,2001.00x 🏆
Valibot35,8000.87x
Zod11,4000.28x

ポイント:

  • ArkTypeめっちゃ速い。Zodの3〜4倍
  • ValibotもArkType近い。Zodよりはずっと速い
  • Zod一番遅い。でも毎秒100万は処理するから普通は問題なし

パフォーマンス大事な場合 vs そうでもない場合

大事:

  • 毎秒数千リクエスト処理するAPI
  • 大量データのバッチ検証
  • エッジ/サーバーレスでCPUコスト気になる時

そうでもない:

  • フォーム検証(毎秒数回程度)
  • 内部ツール(トラフィック少ない)
  • DXの方が大事な時

API:どんな感じか

同じブログ記事スキーマを3つで書いてみました。

作るスキーマ

// - title: 必須、1-200文字 // - content: 必須、100文字以上 // - author: オブジェクト(name, email) // - tags: 1-5個、重複なし // - publishedAt: 任意、過去のみ // - metadata: 任意、文字列の辞書

Zodで書くと

import { z } from 'zod'; const AuthorSchema = z.object({ name: z.string().min(1).max(100), email: z.string().email(), }); const BlogPostSchema = z.object({ title: z.string().min(1).max(200), content: z.string().min(100), author: AuthorSchema, tags: z.array(z.string()) .min(1).max(5) .refine(tags => new Set(tags).size === tags.length, { message: 'タグ重複ダメ' }), publishedAt: z.date() .refine(d => d < new Date(), { message: '過去じゃないとダメ' }) .optional(), metadata: z.record(z.string()).optional(), });

チェーンに慣れてると読みやすい。カスタム検証がちょっと長くなるけど。

ArkTypeで書くと

import { type } from 'arktype'; const Author = type({ name: '1<=string<=100', email: 'string.email', }); const BlogPost = type({ title: '1<=string<=200', content: 'string>=100', author: Author, tags: '1<=string[]<=5', 'publishedAt?': 'Date', 'metadata?': 'Record<string, string>', }).narrow((post, ctx) => { if (post.tags.length !== new Set(post.tags).size) { return ctx.mustBe('重複なしのタグ'); } if (post.publishedAt && post.publishedAt >= new Date()) { return ctx.mustBe('過去の日付'); } return true; });

一番短い。文字列で型表現するの、最初は慣れないかも。

エラーメッセージ

検証失敗した時、何が出るかも大事ですよね。

ArkTypeはそのまま読める

if (result instanceof type.errors) { console.log(result.summary); // "title must be at least 1 characters (was 0) // tags must be 重複なしのタグ" }

ZodとValibotはJSON形式なので、表示用に整形が必要。

再帰型

// Zod: lazy使わないといけない const Category: z.ZodType<Category> = z.lazy(() => z.object({ name: z.string(), children: z.array(Category) }) ); // ArkType: thisって書くだけ const Category = type({ name: 'string', children: 'this[]', });

ArkTypeはthis[]で一発。スッキリ。

エコシステム

ライブラリReact Hook FormtRPCDrizzleプラグイン数
Zod✅ 公式✅ 内蔵✅ あり50個+
Valibot✅ 公式コミュニティ✅ あり〜15個
ArkTypeコミュニティ自作必要〜5個

エコシステムはまだZodが圧倒的。

結論:何選ぶ?

Zod選ぶべき時

  • プラグインたくさん必要
  • チームがZod知ってる
  • 安定性最優先

Valibot選ぶべき時

  • バンドルサイズ気になる(エッジ、ブラウザ)
  • 関数型スタイル好き
  • Zod級の安全性+もっと速いの欲しい

ArkType選ぶべき時

  • パフォーマンスマジで大事
  • TypeScriptの型システム大好き
  • 複雑な変換検証やる

2026年のおすすめ

  1. 新規プロジェクト+パフォーマンス重視:Valibot
  2. チームプロジェクト+安定性重視:Zod
  3. 型マニア+最新技術:ArkType

3つとも優秀です。どれ選んでも失敗しません。

まとめ

TypeScript検証ライブラリ、戦国時代ですね。Zodが道を開いて、Valibotが最適化して、ArkTypeがまた変えた。競争のおかげでみんな良くなりました。

何選んでも、コンパイル時の型安全性+ランタイム検証、両方手に入ります。それが本当の勝ち。

さあ、データ検証しに行きましょう。型安全に 🚀

TypeScriptZodValibotArkTypeValidationSchemaPerformance

関連ツールを見る

Pockitの無料開発者ツールを試してみましょう