世界を動かす技術を、日本語で。

ゾッド 4

概要

  • Zod 4 が正式リリース、パフォーマンスと効率が大幅向上
  • Zod 3との共存 で移行を簡易化、詳細はMigration guide参照
  • zod/v4-mini でバンドルサイズを大幅削減、特に厳しいプロジェクト向け
  • 新機能 :メタデータ管理、再帰型、ローカライズ、エラープリティプリント等
  • API刷新 と設計改善で今後の拡張・連携を強化

Zod 4: 新時代のTypeScriptスキーマバリデーション

リリースと移行戦略

  • Zod 4 は1年間の活発な開発を経て安定版として公開、 パフォーマンス・効率性・新機能 を大幅強化
  • Clerk OSS Fellowship による支援に感謝、開発期間延長にも柔軟に対応
  • 移行の円滑化のため、 Zod 3とZod 4はzod@3.25で同時配信、既存エコシステムとの互換性維持
  • Zod 4の利用/v4サブパスからimportすること
  • 将来的にはnpmで zod@4.0.0 としてパッケージルートからエクスポート予定、zod/v4サブパスも維持
  • 詳細なバージョニング理由や破壊的変更は Migration guide やGitHub issueで確認すること

成長と背景

  • Zod v3.0 (2021年5月リリース)時点:GitHub stars 2,700、週60万ダウンロード
  • 現在(Zod 4) :GitHub stars 37,800、週3,100万ダウンロードに拡大
  • Zod 3の設計限界 を突破し、要望の多かった新機能・パフォーマンス向上・設計改善を一挙実現
  • 最も投票数の多かったオープンissueの9/10を解決、新たな基盤として長期活用を目指す

パフォーマンス・効率性の向上

  • ベンチマーク
    • 文字列パース:14倍高速化
    • 配列パース:7倍高速化
    • オブジェクトパース:6.5倍高速化
  • TypeScriptコンパイル効率
    • tscの型インスタンス生成数:zod/v3で25,000超→zod/v4で約175に削減
    • .extend().omit()の連鎖によるコンパイラ負荷を大幅軽減、10倍高速化
    • tsgo compiler との連携で大規模スキーマでも編集性能を維持

バンドルサイズ削減とzod/v4-mini

  • コアバンドルサイズ
    • zod/v3:12.47kb(gzip)
    • zod/v4:5.36kb(gzip、57%削減)
  • zod/v4-mini 導入
    • 機能APIをラップ関数化し、未使用APIのtree-shakingを容易化
    • zod/v4-mini:1.88kb(gzip、zod@3比で85%削減・6.6倍小型化)
    • バンドルサイズ厳格プロジェクト に推奨、詳細はzod/v4-mini docs参照

新機能・拡張

  • メタデータ管理
    • スキーマに型付きメタデータを付与、schema registryで管理
    • .meta()でグローバル登録、JSON Schema変換時も自動反映
  • 再帰型サポート
    • 型キャスト不要で再帰・相互再帰スキーマをシンプルに定義可能
  • ローカライズAPI
    • エラーメッセージの多言語対応(現時点で英語のみ、今後拡充予定)
  • エラープリティプリント
    • z.prettifyErrorでZodErrorを読みやすい文字列に変換可能
  • string format API刷新
    • z.string().email()等のメソッドは非推奨、z.email()等のトップレベル関数推奨
    • カスタムemail正規表現や共通パターンも提供
  • template literal型サポート
    • TypeScriptのtemplate literal型をバリデーション可能に
  • 数値型フォーマット
    • 固定幅整数・浮動小数点型(int8, uint8, float32等)やBigInt型もサポート
  • 高度なboolean coercion
    • z.stringbool()でenvスタイルの真偽値変換、カスタマイズも可能
  • エラーAPIの統一・刷新
    • errorパラメータに一本化、従来のmessage/invalid_type_error/required_error/errorMapは非推奨
  • discriminated unionの拡張
    • union, pipe, ネストオブジェクト等もサポート、union同士の合成も可能
  • z.literal()の複数値対応
  • refinementの実装改善
    • スキーマ内部で管理し、他のメソッドとの併用が容易に
  • .overwrite()導入
    • 型を変更しない変換処理をrefinementとして記述可能、transformとの違い明確化
  • zod/v4/coreサブパッケージ
    • zod/v4・zod/v4-mini共通の基盤、他ライブラリへの組み込み容易化
    • スキーマライブラリ開発者向けにFor library authors guideも整備

今後・コミュニティ

  • ドキュメント・設計解説記事 を順次公開予定
  • GitHub DiscussionsやX/Bluesky でフィードバック・質問受付
  • ライブラリアーサー向けガイド でZod 3/4両対応やMini対応のベストプラクティスを解説

Zod 4は、TypeScriptバリデーションの新たな標準として、パフォーマンス・拡張性・開発体験を大きく進化させました。今後のエコシステム発展にも注目してください。

Hackerたちの意見

Zodは、見た中での代替案よりずっといいと思う。ただ、こういう明示的なバリデーションが必要っていうのは、現代のウェブ開発が進んできたところでの失敗のように感じる。フルスタック開発が同じ形を表現するのにこんなにたくさんの方法を必要とするのが本当にイライラする:JSの入力バリデーション、API定義のためのSwagger、サーバーサイドの入力バリデーション、スキーマ準拠のためのORM、TypeScriptはサーバーとクライアントで別々の定義が必要なことが多い。ほんとに面倒くさいよね。

でも、こういうものの本質はそこなんだよ。一度やれば、後はダイナミックに他のものを生成できる。だから、Zodのスキーマを一度変更すれば、アプリ全体で型チェックしながら伝播するんだ。Zodのスキーマが真実のソースになるんだよ。

そうだね、少なくとも統合する方法があって、真実のソースとして扱うフォーマットに合意できるようにするべきだよね。他のフォーマットを生成するために。

それ以外にどうやってやるの? trpcみたいなものでフルエンドツーエンドの型安全性を確保することもできるけど、それにはフロントエンドとバックエンドの両方でTypeScriptを使う必要がある(みんながそうするわけじゃないし)し、ウェブプラットフォームにだけ縛られることになる(だからモバイルとかは無理)。

TypeScriptが静的チェック/コンパイル時専用のシステムであることにこだわるのは、全体のエコシステムにとって悲しい傷だよね。TypeScriptにランタイムチェックをしてほしいわけじゃないけど、クラス、関数、オブジェクトのために使える型データをエクスポートしてほしい。TypeScriptは私たちが持っている最良の真実のソースのように感じるけど、実際には私たちが持っているものを反映しようとする試みの多くが独自に進んでいて、自分たちのモデルやビルダーを定義しなきゃいけない。君は反映がミッションの核心部分である5つの主要な領域を挙げていて、それぞれに複数の実装がある。古いTypeScript型エミッターやreflect-metadataがあって、これはランタイムでいくつかの型情報を提供するけど、非常に古いデコレーターやメタデータの仕様を対象にしていて、現在のバージョンではない。どれだけ正確か完全かはあまり分からないけど、TypeScriptが知っていることをどれだけ書き留めているか、どれだけ自分のモデルを定義してエクスポートしているかは分からない。https://www.npmjs.com/package/reflect-metadata もしかしたら、私たちは何かを統一する、集まる寸前にいるのかもしれないけど、今のところTypeScriptを介さずに、まだ別のレイヤーとして。Standard Schemaプロジェクトは、言うまでもなくほとんどのトップバリデーションライブラリからサポートを受けている。でも、これをAPI定義やORMツールに拡張するのは、まだ非常に初期の段階だよ。https://github.com/standard-schema/standard-schema?tab=readm...

すべてのAPIは実験的で、常に変化し進化している状態にあるよ、ウェブも含めてね。現状維持が許されるのは、ただ物事を終わらせたいクライアントや雇用者のためだけだよね。そういう文脈では、こういう複雑なレイヤーがあるおかげで、少なくとも請求可能な時間が増えるってことだね。

drizzleとHono、zodを使ってクライアントを作ってるんだ。だから、UIからクライアント、サーバー、DBまで、同じバリデーションと形を保ってるよ。

フルスタック開発が同じ形を説明するのにこんなに多くの方法を必要とするのは本当にイライラするよね。JSの入力バリデーション、API定義のためのSwagger、サーバーサイドの入力バリデーション、スキーマ準拠のためのORM、TypeScriptはサーバーとクライアントで別々の定義が必要だったりするし。めっちゃ面倒くさい。現代のウェブ開発が複雑だって文句を言ってる人たちが、TypeScript(もしそれが君のTSスキーマ定義とバリデーションライブラリなら)で全部置き換えようなんて提案したら、みんなビビるだろうね。

データをあちこちで再定義する必要は普通はないよ。zodに変換するためのコンバーターが山ほどあるし、zodから他のものへの変換も同様。もし既にJSONスキーマやswaggerスキーマがあるなら、そこからzodを生成すればいいし。TypeScriptのORMを使ってるなら、$10賭けてもいいけど、zodのジェネレーターがあるはずだよ。正直、zodはすごく人気が出てきて、私にとってはスタックの他の部分が頼れる統一的なスキーマ定義になってる。しかも、直接型を定義するから、開発者たちが実際に最新の状態に保ってくれるし(私の会社のswaggerドキュメントは常に変更に遅れをとってる)。

私は専門家じゃないけど、JSON-Schemaがいい選択肢かもしれないって思った。スキーマベースだから、TypeScriptじゃない言語でもバリデーターを実装できるし。https://ajv.js.org はそんなJSONスキーマライブラリの一つだよ。Zodはこれと比べてどうなの?

まあ、ZodはJSONの検証だけじゃないんだよ。変換なしではJSONで表現できないオブジェクト(日時やクラスのインスタンスなど)の検証もサポートしてる。もし必要なら、JSONの変換器としても使えるよ。例えば、スキーマを作って文字列を受け入れ、それをISO日付文字列として検証し、Dateオブジェクトとして出力することもできるんだ。

Zod 4はZodスキーマをJSON-Schemaに変換することをサポートしてる(ネイティブで、これまでもサードパーティのライブラリで可能だったけど)。一つの大きな違いは、前処理やリファインができること。Zodを使うと、検証を実行する前にコールバックを提供できるから、すごく便利でJSONでは表現できないことなんだ。これ、思ったよりも頻繁に役立つよ。例えば、MM/DD/YYYYをDD/MM/YYYYに変換してから日付として検証するみたいな感じ。

それはいい選択だね。その場合、TypeBoxはそれを生成するのに良い方法だよ。AVJや独自のスキーマバリデーションシステムも使えるし(こっちの方が速いけど、AVJはデータベースとかに対して非同期バリデーションオプションがあるから注意してね)。

JSON Schemaは、言語を超えたバリデーションの方法だよ。OpenAPIに包み込めば、素晴らしいAPIドキュメントも無料で手に入る。

ここで誰かが、私がずっと疑問に思っていた質問に答えてくれるか気になる。Zodが正しい方向にあるかもしれないって聞いたけど、ドキュメントを読んでもどう進めていけばいいのか分からない。例えば、サーバーから返される型が、サーバーAPIが表現できるよりも複雑な型を持っている場合。例えば、api/:postid/authorがUserを返すけど、それは普通のUserか匿名のUserかもしれなくて、その場合はusernamelocationなどのフィールドがnullで返ってくる。だから、この場合は識別されたユニオンを使ってUserオブジェクトを表現したいかもしれない。他のエンドポイントから返ってくる他のオブジェクトも、何らかの型の変更が必要かもしれない。例えば、Userは時々Post[]を持っていて、もしそのPostがモデレーターからのものであれば、特別な属性を持っているかもしれない - また別の識別されたユニオン。過去にはnormalizeUser()やnormalizePost()みたいな関数を書いてこの問題を解決してきたけど、すぐに本当にゴチャゴチャになっちゃう。異なるエンドポイントがUser/Postモデルの異なる部分集合を返すから、各エンドポイントごとにnormalizePostの異なるバージョンを5つも書かなきゃいけなくなって、ほんとに面倒くさい。みんなはこの問題をどう解決してるの?

ユニオンか、オプショナルフィールドか。

使い方についてもっと知っていないと難しいけど、ユニオンのすべてのタイプに判別プロパティ(例えば「user_type」)を追加すると、一般的なケースと特定のケースを扱いやすくなるよ。例えば、if (user.user_type === 'authenticated') { // user.nameを使って何かする。タイプシステムがそれを知っているからね }

理想的な世界では、Userの形状が何であるかの真実のソースが一つあるべきだね(それはUserとAnonymousUserの判別ユニオンかもしれない)。フルスタックTSがない場合、これがどうなるかというと:(Pythonバックエンドの場合)Pydanticモデル+Userのさまざまな形状のユニオン、そしてOpenAPI/GraphQLスキーマ生成+TSクライアント用のコード生成になるかも。

判別ユニオンを使うと思うよ。const MyResult = z.discriminatedUnion("status", [ z.object({ status: z.literal("success"), data: z.string() }), z.object({ status: z.literal("failed"), error: z.string() }), ]); モデレーター用の特別な属性がたくさんあっても、それをすべてリストアップしたりチェックしたりしたくない場合は、パススルーの振る舞いを定義できるよ。異なるスキーマを持つ異なるメソッドがあって、共通のスキーマの一部を共有している場合は、共有部分のオブジェクトを定義して、追加のフィールドを持つ共有オブジェクトスキーマを含むオブジェクトを作成できるよ。たくさんの異なる可能性があると、混乱するけど、あなたにはすでにそうなっているみたいだから、バリデーターが少なくともその混乱を検証できるかもしれないね。

これは君のケースには役立たないかもしれないけど、これがGraphQLが発明された理由なんだ。GQLクエリ用のTSライブラリは、選択したフィールドの形状からレスポンスの形状を動的に推測できるんだ。例えば、クエリ query { user { username posts { text } } }type Response = { user: { username: string posts: Array } } になって、{ user { username } } だけのクエリだとpostsプロパティは完全に省略されるんだ。

サーバーは型をエクスポートするべきだよ。クライアントで手動で型を書くのは意味がない。サーバーは送信しているデータを知っているから、その情報をメタデータとしてクライアントに提供するべきなんだ。実際には、PythonのバックエンドがPydanticスキーマを使って、自動的にクライアントが型を生成するためのOpenAPI仕様を生成するってこともあるよ。

Zod 4は良さそうだけど、最新の改善があってもArkTypeの方がまだ圧倒的に速いよ。時には後方互換性や構文の互換性のために、完全に新しいライブラリよりもずっと速くするのが難しいこともある。最近、私たちのプロジェクトのためにこういったツールの分析を行って、部分的にこの理由でArkTypeを選ぶことにしたんだ。他の理由はTypeScriptの使いやすさが良かったから。

彼らのスピードメトリクスを見てたんだけど、どこでスピードが違いを生むのか説明してもらえる?うちはフォームの検証にしかzodを使ってないから、「これってどう重要なの?」ってずっと考えてる。もしかして、高スループットのAPI入力メッセージを検証するために使ってる人がいるのかな、パフォーマンスがもっと重要になるような場面で?

面白いね、それは俺のリサーチには全然出てこなかった。特にTypeScriptの使いやすさを探してたんだけど、やっぱりZodからは移行しないと思う。

TypeBoxよりArkTypeの方がいい理由は?

ArkTypeは使うのが地獄だけど、zodは使いやすいね。

Zodチームの新しいリリース、おめでとう!ちょっとネガティブに聞こえるかもしれないけど、移行ガイドに書かれている破壊的変更の数を考えると、ゾッとしちゃうよ。Zodに大きく依存しているプロジェクトにとっては、先が思いやられるね—開発者の注意と時間がたくさん必要になるから。仕事で4〜5年経ったフロントエンドプロジェクトをいくつか維持してきたから、すごく共感するよ。私の経験では、大きなReactプロジェクトは多くのライブラリに依存していることが多くて、それぞれが大きな変更を行うと—時にはほとんどドキュメントがない状態で—すぐに圧倒されちゃう。正直、JavaScriptを使う上で一番嫌な部分の一つだよ。すべてを同期させてスムーズに動かすのが、常に uphill battle のように感じる。

Zodに大きく依存しているプロジェクトにとっては、先が思いやられるね—開発者の注意と時間がたくさん必要になるから。あるいは、LLMを使うだけでもいいかもね。

だから、彼らはデュアルアベイラビリティのアプローチを取ってるんだよ、別の「ミニ」エディションを用意して。パッケージマネージャーをいじらずに段階的な移行が簡単にできるからね。「ミニ」エディションに興味がない消費者は、その部分を気にしなくていい。でも、「ミニ」エディションの利点はツリーシェイキングにとってすごく大きいから、代替品の開発を促進してたんだ。zodはそれをやるか(そして利益を得るか)、それとも廃止するかの選択を迫られてたんだ。

俺も100%同意だわ。いくつかの大きなNext.jsアプリを運営してるんだけど、去年はNext.js 14から15にアップデートしたせいで、キャッシュの大きな変更があったり、Next.jsのページからアプリルーターに移行したり、React 18から19、Eslint 8から9、Tailwind 3から4に移行したりで、正直悪夢だった。Djangoで作っておけばよかったと思ってる。Tailwind 3から4への移行が一番辛かったかも、これは予想外だった。

ユーザーとZodの関連ライブラリのエコシステムのために移行プロセスを簡素化するために、Zod 4はZod 3と一緒にzod@3.25リリースの一部として公開されるよ。[...] "/v4"サブパスからZod 4をインポートするのは、依存関係管理システムの絶対的な災害だよ。ピア依存関係が壊れすぎていて、v4はv3のふりをしなきゃいけなかったんだ。

Node.jsとNPMは、LLMが存在する前に初めて作られた時、なんか雰囲気でコーディングされた気がする。ちょっとしたハックみたいなもので、偶然にもすごく人気が出たんだよね。編集:考えてみると、これってJavaScriptの起源の話でもあるから、なんかぴったりだね。

もうすでにzod 4のベータ版を使ってて、すごく改善されてるんだけど、巨大なコードベースが必要なmoduleResolutionの設定に対応できないから、アップグレードできないんだ… せめてレガシーレイヤーなしでメジャーバージョンとして公開してほしいな。編集:ここで説明されてる理由を見たよ:https://github.com/colinhacks/zod/issues/4371 要約すると、彼はエコシステム全体で「バージョンバンプの雪崩」を引き起こしたくないみたい。(でも、僕はそれは起こらないと思う。彼らはまだ修正をバックポートして、v3をしばらくサポートできるから、今やってるみたいにね)

ピア依存関係が壊れすぎて、v4がv3のふりをしなきゃいけなかった ここでの結論が正しいかはわからないけど、zod v4はv3に含まれてるから、消費者が徐々に移行できるようになってると思う。つまり、すべての使用箇所を一つずつimport ... from 'zod/v4'にリファクタリングして、それが終わったら完全にv4にアップグレードするって感じ。

何年もnpmだけ使ってきたせいで盲目になってるかもしれないけど、v3からv4に段階的に移行するためのより良い方法って何かある?

他の人が挙げたこととは別に、leerobも指摘してるけど、APIが異なる可能性を示唆してるね。 https://x.com/leerob/status/1924504939818008791

ネガティブなことにはみんな投票する気がする。これはnpmの制限というより、npm自体に問題があるわけじゃなくて、ブレーキングチェンジが多いライブラリの進化を実現するための実用的な方法なんだよね。

著者です。興味がある人のために、このアプローチの理由についてここにかなり詳細な説明を書きました[0]。最終的に、npmはZodが直面している状況をうまく管理できないのはその通りです。でもZodは、他のほとんどのライブラリが直面しない制約に縛られています。直接「zod」からインターフェースやクラスをインポートして、自分たちの公開APIで使っているライブラリが数十、数百あるんです。これらのライブラリはZodに直接結びついているので、Zodが新しいメジャーバージョンを出すたびに、新しいメジャーバージョンを公開する必要があります。それ自体は孤立していると合理的ですが、Zodの場合は「バージョンの雪崩」を引き起こして、関係者全員にとって痛い思いをさせることになります。自己中心的に言えば、エコシステムの大部分がv3に永遠に固定される結果になるんじゃないかと思っています。私が最終的に採用したアプローチは、Golangのやり方に似ています。要するに、特定のパッケージは新しいブレーキングバージョンを決して公開せず、新しいブレーキングリリースが出るときに新しいサブパスを追加するだけです。TypeScriptエコシステムでは、これによりライブラリはzod@^3.25.0に対して単一のピア依存関係を設定し、「zod/v3」と「zod/v4」から必要なものをインポートすることで両方のバージョンを同時にサポートできます。これにより、Zodのエンドユーザーにも良いオプトインの段階的なアップグレードパスが提供されます。[0] https://github.com/colinhacks/zod/issues/4371

これはnpmだけの問題じゃないよ。他のトランジティブ依存関係が古いバージョンに依存している依存関係があるのは、実際に他のエコシステムでも起こる問題だよ。むしろ、npmは必要に応じて複数のバージョンを同時に実行したり、トランジティブ依存関係の一部を選択的にオーバーライドしたりできるから、逃げ道が多いんだ。どのパッケージ管理システムがこの問題の解決策を持ってるの?Mavenのような「安定した」プラットフォームですら、新しい名前空間の下で新しいバージョンを公開してこの無駄に対処してるし(Apache Commonsがv2からv3に移行したみたいに)。

ひどい、今は使わない。私のIDEはどちらかを入れ替えてインポートするから、めちゃくちゃになるよ。

新しいプロジェクトにZodを取り入れ始めたばかりなんだ。こんなタイミングでできてよかった。v4に移行するために、見てる限りだとかなりの変更が必要だったと思う。

このネガティブな反応には驚いたよ。zod v4の初期バージョンを試してみたけど、新しいAPIが気に入った。ただ、移行パスについてはすごく心配してた。新しいパッケージ名で公開することを提案しようと思ってたくらい。でも、著者のアプローチはすごく賢いね。依存関係が全部更新されるのを待たずに、すぐにv4を使い始められるから。素晴らしい!

うん、いいルートだね。バリデーションみたいなことに対して、全てを一度に移行するなんて無理だよ。

著者です、何でも聞いてください!バージョニングについてですが、興味がある人のために、このアプローチの理由についてここにかなり詳細な説明を書きました[0]。最終的にnpmはZodが直面している状況をうまく管理できないのはその通りです。Zodは、他のほとんどのライブラリが直面しない制約に縛られています。具体的には、Zodからインターフェースやクラスを直接インポートして、自分たちの公開APIで使っているライブラリが数十、数百あります。これらのライブラリはZodに直接結びついているので、Zodが新しいメジャーバージョンを出すたびに、新しいメジャーバージョンを公開する必要があります。それ自体は孤立していると合理的ですが、Zodの場合は「バージョンの雪崩」を引き起こして、関係者全員にとって痛い思いをさせることになります。自己中心的に言えば、エコシステムの大部分がv3に永遠に固定される結果になるんじゃないかと思っています。私が最終的に採用したアプローチは、Golangのやり方に似ています。要するに、特定のパッケージは新しいブレーキングバージョンを決して公開せず、新しいブレーキングリリースが出るときに新しいサブパスを追加するだけです。TypeScriptエコシステムでは、これによりライブラリはzod@^3.25.0に対して単一のピア依存関係を設定し、「zod/v3」と「zod/v4」から必要なものをインポートすることで両方のバージョンを同時にサポートできます。これにより、Zodのエンドユーザーにも良いオプトインの段階的なアップグレードパスが提供されます。[0] https://github.com/colinhacks/zod/issues/4371

短期的な痛みが少ない道がしばしば最良の道だよね。Pythonエコシステムの古い人たちは、Python 2/3の移行の混乱をみんな覚えてる。

まずは、頑張ってくれてありがとう!新しい機能で私のローカルハックの多くがなくなるよ!便利さのために、フォーム名のタイプミスを避けるために、私は自分のバージョンのhttps://github.com/raflymln/zod-key-parserを使ってる。こんなのがライブラリに直接実装されてないのは驚きだよ。これがZodの範囲外だと思うのか、それともまだ実装する時間がなかっただけなのか、気になるな。(これについての議論はこちら: https://github.com/colinhacks/zod/discussions/2134)

仕事に感謝!アップグレードを楽しみにしてるよ。特にtscに関するパフォーマンス向上は、うちの比較的大きなコードベースにはすごくありがたいし、識別されたユニオンの変更も、今までうまくいかなかった特定のシナリオで大いに助けになると思う。とはいえ、特別な状況に応じたちょっと変わったバージョニングの理由は理解してるけど、zodのバージョン衝突を気にしなくていい4.0.0パッケージがあればいいなって思うよ。少なくとも、npm ls zodでは自分たちの依存関係しか返ってこないから。もし理解が合ってれば、インポートを「zod/v4」に適応する必要があるみたいで、これはすごく騒がしい変更になりそうだし、IDEが'zod'から自動インポートする時に結構な頭痛の種になるだろうね。それをリントルールでキャッチしなきゃいけないし。でも、全体的にはすごく期待できるアップグレードに聞こえるから、改めて感謝!

記事に書いてあるかもしれないけど、モバイルで見てるからごめんね。TS[0]の.optional()の修正は9/10のトップ問題の一部として直るの?これがZodでの最大の痛点なんだ…でもそれでもZodはすごく良いから、なんとか対処してるよ :) エコシステムの一部として素晴らしいものをありがとう。[0] https://github.com/colinhacks/zod/issues/635

ブレイキングチェンジをリリースすることを考慮してくれて本当に感謝してる。すべてのライブラリが君の方法論を採用できるわけじゃないけど、もっと多くのライブラリがそうしてくれたらいいなと思う、フロントエンドプラットフォームエンジニアとして。

再帰スキーマの型推論を解決するツイートを見たよ。この問題の解決策はかなり簡単そうに見えるけど、本当にゲッターを使うだけで解決できるの?それとも、私が理解できていない追加の複雑さがあるのかな?

両方のバージョンを一緒に公開することで互換性の問題が解決されるけど、ツリーシェイキングが有効じゃない環境ではライブラリがさらに重くなるんだよね。例えば、React Nativeでは、ツリーシェイキングを機能させるためにいろいろと手間がかかるし(デフォルトのメトロバンドラーから離れなきゃいけないことも多いから、これが結構厄介なんだよね)。

他の多くのライブラリが世界を壊す中、壊さないでいてくれて心から感謝!フロントエンド開発の世界では、基本的だけど補助的なライブラリの破壊的変更は本当に痛いから、もう笑えないよね。

私が最終的に使ったアプローチは、Golangのやり方に似てる。要するに、特定のパッケージは新しい破壊的バージョンを公開しないで、新しい破壊的リリースが行われるときに新しいサブパスを追加するだけなんだ。TypeScriptエコシステムでは、ライブラリがzod@^3.25.0に対して単一のピア依存関係を設定できて、必要なものを「zod/v3」と「zod/v4」からインポートすることで両方のバージョンを同時にサポートできるってこと。これにより、Zodのエンドユーザーにとっても、段階的なアップグレードパスが提供されるのがいいね。これは非常に理にかなってるし、古いバージョンのセキュリティアップデートも同じコードベースのリリースで提供できるってことだ。

v3とv4のスキーマ同士で互換性はあるのかな?何百、下手したら何千ものZodスキーマがあって、その多くが他のスキーマを継承したり拡張したりしてるんだ。両方のバージョンがうまくやり取りできないと、段階的なアップグレードは難しいと思う。でも、最悪の場合500行のスキーマファイルが80万行の生成された型に変わる問題が解決するかどうか楽しみにしてるよ。

自分のSaaSを運営していて、数千人のユーザーがいるフルスタック開発者として、SPAを作らないことに決めたおかげで、どれだけの問題に気づいていないかを時々思い知らされることがある。ZodやArkTypeみたいなものが必要だなんて思ったこともなかったし、初めて聞いたけど、私には必要ない。SPAを作るためにどれだけの労力や複雑さ、ツールが必要なのか、全く理解できないよ。SPAを作らない選択をすれば、全く存在しない問題のクラスがあるんだ。一方で、私はブラウザを本来の使い方で使ってる:フルページリロード、バックエンド開発のみ、たまにLaravel Livewireみたいなバックエンド専用フレームワークを使った反応性。アクセス制御からバリデーション、状態管理まで、すべてがとてもシンプル。そう、私のアプリは速くて、反応的で、モダンで、SEOにも優しくて、数千人のユーザーにサービスを提供してる。

あなたのSaaSは何ですか?SPAなしで素晴らしい製品を作ることができたユースケースを見てみたいです。

じゃあ、サーバーサイドのバリデーションはどうやってるの?今のところ、あなたが防御的にたくさんのif文を書いてるだけのように思えるけど。もっと悪いことに、HTMLのクライアントサイドのフォームバリデーションだけに頼ってるのかな。

ZodはSPAsとは関係ないし、ただのフロントエンドツールじゃないよ。コードの中で入力をバリデートしないの?

目を閉じれば、存在しない問題のクラスがたくさんあるよ。

データパイプラインの一部として使われているバックエンド専用のZodスキーマがめちゃくちゃ多いから、SPAの問題を解決するためだけに存在してるわけじゃないみたいだね。