Skip to content

feat!: migrate to zod 4 (BREAKING — peer dep ^4.4.3)#6

Merged
Changsik00 merged 1 commit into
mainfrom
chore/upgrade-zod-4
May 18, 2026
Merged

feat!: migrate to zod 4 (BREAKING — peer dep ^4.4.3)#6
Changsik00 merged 1 commit into
mainfrom
chore/upgrade-zod-4

Conversation

@Changsik00
Copy link
Copy Markdown
Owner

Summary

zod 3 → 4 migration. Public API and runtime semantics preserved; consumer migration is mechanical (schema-definition syntax only).

Why

Required to allow @env-kit/node-settings to be wrapped from a zod 4 monorepo (e.g., service-foundry ADR-0002 + ADR-0010 — see spec-x-auth-foundation-prep).

Internal changes

  • _def.typeName_def.type (lower-cased values)
  • ZodEnum / ZodNativeEnum unified under `enum`
  • ZodEffects / ZodPipeline → `pipe` (with `in` / `out`)
  • `_def.defaultValue` is a direct value (zod 3 was a thunk)
  • `ZodError.errors` → `ZodError.issues`
  • ZodError path stringified (zod 4 may emit numeric segments)

Verification

  • node_modules/.bin/tsc --noEmit — 0 errors
  • vitest run294/294 pass
  • tsc -b tsconfig.build.json — dist builds clean

Migration guide for consumers

Bump zod to ^4.4.3. Schema syntax adjustments at consumer sites only (out of this library's surface):

// zod 3
z.string().email()
z.string().uuid()

// zod 4
z.email()
z.uuid()

ZodError.errors consumers must rename to .issues.

Test plan

  • All existing tests pass under zod 4.4.3
  • typecheck clean
  • build succeeds
  • (manual) npm publish + consumer (service-foundry) verifies

🤖 Generated with Claude Code

zod 4 internal API changes required by this migration:

- _def.typeName → _def.type (lower-cased: "ZodObject" → "object" etc.)
- ZodEnum and ZodNativeEnum unified under "enum" (single .options accessor)
- ZodEffects / ZodPipeline collapsed into single "pipe" type (def.in / def.out)
- _def.defaultValue is now a direct value (zod 3 stored a () => unknown thunk)
- ZodError.errors → ZodError.issues
- ZodError path may contain numeric segments — explicit String() join

Public API and runtime semantics are preserved. Consumer migration is
mechanical (mostly z.string().email() → z.email() at schema definition
sites — outside this library's surface).

All 294 tests pass under zod 4.4.3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Changsik00 Changsik00 merged commit 914bbd0 into main May 18, 2026
9 checks passed
@Changsik00 Changsik00 deleted the chore/upgrade-zod-4 branch May 18, 2026 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant