From ed1351c4fb92f84657a0c1a2af5ccef2484f7bd7 Mon Sep 17 00:00:00 2001 From: "Henry Q. Dineen" Date: Thu, 16 Oct 2025 12:46:55 -0400 Subject: [PATCH] [compiler] improve zod v3 backwards compat (#34877) ## Summary When upgrading to `babel-plugin-react-compiler@1.0.0` in a project that uses `zod@3` we are running into TypeScript errors like: ``` node_modules/babel-plugin-react-compiler/dist/index.d.ts:435:10 - error TS2694: Namespace '"/REDACTED/node_modules/zod/v3/external"' has no exported member 'core'. 435 }, z.core.$strip>>>; ~~~~ ``` This problem seems to be related to d6eb735938bc67b41ad723206ea395ba4d761139, which introduced zod v3/v4 compatibility. Since `zod` is bundled into the compiler source this does not cause runtime issues and only manifests as TypeScript errors. My proposed solution is this PR is to use zod's [subpath versioning strategy](https://zod.dev/v4/versioning?id=versioning-in-zod-4) which allows you to support v3 and v4 APIs on both major versions. Changes in this PR include: - Updated `zod` import paths to `zod/v4` - Bumped min `zod` version to `^3.25.0` for zod which guarantees the `zod/v4` subpath is available. - Updated `zod-validation-error` import paths to `zod-validation-error/v4` - Bumped min `zod-validation-error ` version to `^3.5.0` - Updated `externals` tsup configuration where appropriate. Once the compiler drops zod v3 support we could optionally remove the `/v4` subpath from the imports. ## How did you test this change? Not totally sure the best way to test. I ran `NODE_ENV=production yarn workspace babel-plugin-react-compiler run build --dts` and diffed the `dist/` folder between my change and `v1.0.0` and it looks correct. We have a `patch-package` patch to workaround this for now and it works as expected. ```diff diff --git a/node_modules/babel-plugin-react-compiler/dist/index.d.ts b/node_modules/babel-plugin-react-compiler/dist/index.d.ts index 81c3f3d..daafc2c 100644 --- a/node_modules/babel-plugin-react-compiler/dist/index.d.ts +++ b/node_modules/babel-plugin-react-compiler/dist/index.d.ts @@ -1,7 +1,7 @@ import * as BabelCore from '@babel/core'; import { NodePath as NodePath$1 } from '@babel/core'; import * as t from '@babel/types'; -import { z } from 'zod'; +import { z } from 'zod/v4'; import { NodePath, Scope } from '@babel/traverse'; interface Result { ``` Co-authored-by: Henry Q. Dineen --- .../babel-plugin-react-compiler/package.json | 4 ++-- .../src/Entrypoint/Options.ts | 4 ++-- .../src/HIR/Environment.ts | 4 ++-- .../babel-plugin-react-compiler/src/HIR/HIR.ts | 2 +- .../src/HIR/TypeSchema.ts | 2 +- .../src/Utils/TestUtils.ts | 2 +- .../eslint-plugin-react-compiler/package.json | 4 ++-- .../eslint-plugin-react-compiler/tsup.config.ts | 9 ++++++++- .../packages/react-compiler-healthcheck/package.json | 4 ++-- .../react-compiler-healthcheck/tsup.config.ts | 2 ++ compiler/packages/react-mcp-server/package.json | 2 +- compiler/packages/react-mcp-server/src/index.ts | 2 +- compiler/packages/snap/package.json | 4 +++- compiler/packages/snap/src/sprout/evaluator.ts | 4 ++-- compiler/yarn.lock | 12 ++++++------ packages/eslint-plugin-react-hooks/package.json | 4 ++-- scripts/rollup/bundles.js | 2 ++ yarn.lock | 10 +++++----- 18 files changed, 45 insertions(+), 32 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/package.json b/compiler/packages/babel-plugin-react-compiler/package.json index 8d3f1c8ae6..7647bcab1c 100644 --- a/compiler/packages/babel-plugin-react-compiler/package.json +++ b/compiler/packages/babel-plugin-react-compiler/package.json @@ -52,8 +52,8 @@ "react-dom": "0.0.0-experimental-4beb1fd8-20241118", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", - "zod": "^3.22.4 || ^4.0.0", - "zod-validation-error": "^3.0.3 || ^4.0.0" + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" }, "resolutions": { "./**/@babel/parser": "7.7.4", diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts index 450972a460..2a117b4661 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts @@ -6,7 +6,7 @@ */ import * as t from '@babel/types'; -import {z} from 'zod'; +import {z} from 'zod/v4'; import { CompilerDiagnostic, CompilerError, @@ -20,7 +20,7 @@ import { tryParseExternalFunction, } from '../HIR/Environment'; import {hasOwnProperty} from '../Utils/utils'; -import {fromZodError} from 'zod-validation-error'; +import {fromZodError} from 'zod-validation-error/v4'; import {CompilerPipelineValue} from './Pipeline'; const PanicThresholdOptionsSchema = z.enum([ diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts index 7889e13c2f..a31ef1c336 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts @@ -6,8 +6,8 @@ */ import * as t from '@babel/types'; -import {ZodError, z} from 'zod'; -import {fromZodError} from 'zod-validation-error'; +import {ZodError, z} from 'zod/v4'; +import {fromZodError} from 'zod-validation-error/v4'; import {CompilerError} from '../CompilerError'; import {Logger, ProgramContext} from '../Entrypoint'; import {Err, Ok, Result} from '../Utils/Result'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index 4d2d4ed80d..41e957a546 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -16,7 +16,7 @@ import {assertExhaustive} from '../Utils/utils'; import {Environment, ReactFunctionType} from './Environment'; import type {HookKind} from './ObjectShape'; import {Type, makeType} from './Types'; -import {z} from 'zod'; +import {z} from 'zod/v4'; import type {AliasingEffect} from '../Inference/AliasingEffects'; import {isReservedWord} from '../Utils/Keyword'; import {Err, Ok, Result} from '../Utils/Result'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/TypeSchema.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/TypeSchema.ts index 42c7d2d89d..eeaaebf7a3 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/TypeSchema.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/TypeSchema.ts @@ -6,7 +6,7 @@ */ import {isValidIdentifier} from '@babel/types'; -import {z} from 'zod'; +import {z} from 'zod/v4'; import {Effect, ValueKind} from '..'; import { EffectSchema, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts b/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts index b28879f369..e84c1e57aa 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {fromZodError} from 'zod-validation-error'; +import {fromZodError} from 'zod-validation-error/v4'; import {CompilerError} from '../CompilerError'; import { CompilationMode, diff --git a/compiler/packages/eslint-plugin-react-compiler/package.json b/compiler/packages/eslint-plugin-react-compiler/package.json index 6c95bf495c..3dd77d0e8b 100644 --- a/compiler/packages/eslint-plugin-react-compiler/package.json +++ b/compiler/packages/eslint-plugin-react-compiler/package.json @@ -15,8 +15,8 @@ "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", - "zod": "^3.22.4 || ^4.0.0", - "zod-validation-error": "^3.0.3 || ^4.0.0" + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" }, "devDependencies": { "@babel/preset-env": "^7.22.4", diff --git a/compiler/packages/eslint-plugin-react-compiler/tsup.config.ts b/compiler/packages/eslint-plugin-react-compiler/tsup.config.ts index 4b4f526439..716c2ffff3 100644 --- a/compiler/packages/eslint-plugin-react-compiler/tsup.config.ts +++ b/compiler/packages/eslint-plugin-react-compiler/tsup.config.ts @@ -10,7 +10,14 @@ import {defineConfig} from 'tsup'; export default defineConfig({ entry: ['./src/index.ts'], outDir: './dist', - external: ['@babel/core', 'hermes-parser', 'zod', 'zod-validation-error'], + external: [ + '@babel/core', + 'hermes-parser', + 'zod', + 'zod/v4', + 'zod-validation-error', + 'zod-validation-error/v4', + ], splitting: false, sourcemap: false, dts: false, diff --git a/compiler/packages/react-compiler-healthcheck/package.json b/compiler/packages/react-compiler-healthcheck/package.json index 61825b73d8..5c3d2f412d 100644 --- a/compiler/packages/react-compiler-healthcheck/package.json +++ b/compiler/packages/react-compiler-healthcheck/package.json @@ -17,8 +17,8 @@ "fast-glob": "^3.3.2", "ora": "5.4.1", "yargs": "^17.7.2", - "zod": "^3.22.4 || ^4.0.0", - "zod-validation-error": "^3.0.3 || ^4.0.0" + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" }, "devDependencies": {}, "engines": { diff --git a/compiler/packages/react-compiler-healthcheck/tsup.config.ts b/compiler/packages/react-compiler-healthcheck/tsup.config.ts index 7addc79bf9..7d2c738dc7 100644 --- a/compiler/packages/react-compiler-healthcheck/tsup.config.ts +++ b/compiler/packages/react-compiler-healthcheck/tsup.config.ts @@ -18,7 +18,9 @@ export default defineConfig({ 'ora', 'yargs', 'zod', + 'zod/v4', 'zod-validation-error', + 'zod-validation-error/v4', ], splitting: false, sourcemap: false, diff --git a/compiler/packages/react-mcp-server/package.json b/compiler/packages/react-mcp-server/package.json index 4d744c1d66..07dc378de1 100644 --- a/compiler/packages/react-mcp-server/package.json +++ b/compiler/packages/react-mcp-server/package.json @@ -24,7 +24,7 @@ "html-to-text": "^9.0.5", "prettier": "^3.3.3", "puppeteer": "^24.7.2", - "zod": "^3.22.4 || ^4.0.0" + "zod": "^3.25.0 || ^4.0.0" }, "devDependencies": { "@types/html-to-text": "^9.0.4", diff --git a/compiler/packages/react-mcp-server/src/index.ts b/compiler/packages/react-mcp-server/src/index.ts index 9c47346b3c..e5bd794107 100644 --- a/compiler/packages/react-mcp-server/src/index.ts +++ b/compiler/packages/react-mcp-server/src/index.ts @@ -7,7 +7,7 @@ import {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js'; import {StdioServerTransport} from '@modelcontextprotocol/sdk/server/stdio.js'; -import {z} from 'zod'; +import {z} from 'zod/v4'; import {compile, type PrintedCompilerPipelineValue} from './compiler'; import { CompilerPipelineValue, diff --git a/compiler/packages/snap/package.json b/compiler/packages/snap/package.json index 60530f01dd..085422ab83 100644 --- a/compiler/packages/snap/package.json +++ b/compiler/packages/snap/package.json @@ -37,7 +37,9 @@ "react": "0.0.0-experimental-4beb1fd8-20241118", "react-dom": "0.0.0-experimental-4beb1fd8-20241118", "readline": "^1.3.0", - "yargs": "^17.7.1" + "yargs": "^17.7.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" }, "devDependencies": { "@babel/core": "^7.19.1", diff --git a/compiler/packages/snap/src/sprout/evaluator.ts b/compiler/packages/snap/src/sprout/evaluator.ts index 8af8487d01..ba44f01b0a 100644 --- a/compiler/packages/snap/src/sprout/evaluator.ts +++ b/compiler/packages/snap/src/sprout/evaluator.ts @@ -9,8 +9,8 @@ import {render} from '@testing-library/react'; import {JSDOM} from 'jsdom'; import React, {MutableRefObject} from 'react'; import util from 'util'; -import {z} from 'zod'; -import {fromZodError} from 'zod-validation-error'; +import {z} from 'zod/v4'; +import {fromZodError} from 'zod-validation-error/v4'; import {initFbt, toJSON} from './shared-runtime'; /** diff --git a/compiler/yarn.lock b/compiler/yarn.lock index daafc705fd..764200c2ce 100644 --- a/compiler/yarn.lock +++ b/compiler/yarn.lock @@ -11505,17 +11505,17 @@ zod-to-json-schema@^3.24.1: resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz" integrity sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g== -"zod-validation-error@^3.0.3 || ^4.0.0": +"zod-validation-error@^3.5.0 || ^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-4.0.2.tgz#bc605eba49ce0fcd598c127fee1c236be3f22918" integrity sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ== -"zod@^3.22.4 || ^4.0.0": - version "4.1.11" - resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.11.tgz#4aab62f76cfd45e6c6166519ba31b2ea019f75f5" - integrity sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg== - zod@^3.23.8, zod@^3.24.1: version "3.24.3" resolved "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz" integrity sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg== + +"zod@^3.25.0 || ^4.0.0": + version "4.1.12" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.12.tgz#64f1ea53d00eab91853195653b5af9eee68970f0" + integrity sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ== diff --git a/packages/eslint-plugin-react-hooks/package.json b/packages/eslint-plugin-react-hooks/package.json index a22448f11c..9a8f8ac353 100644 --- a/packages/eslint-plugin-react-hooks/package.json +++ b/packages/eslint-plugin-react-hooks/package.json @@ -42,8 +42,8 @@ "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", - "zod": "^3.22.4 || ^4.0.0", - "zod-validation-error": "^3.0.3 || ^4.0.0" + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" }, "devDependencies": { "@babel/eslint-parser": "^7.11.4", diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index c66b43797f..0a7b17ec2c 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -1255,7 +1255,9 @@ const bundles = [ '@babel/core', 'hermes-parser', 'zod', + 'zod/v4', 'zod-validation-error', + 'zod-validation-error/v4', 'crypto', 'util', ], diff --git a/yarn.lock b/yarn.lock index 73519b9f69..ad8a3f0085 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18245,12 +18245,12 @@ zip-stream@^2.1.2: compress-commons "^2.1.1" readable-stream "^3.4.0" -"zod-validation-error@^3.0.3 || ^4.0.0": +"zod-validation-error@^3.5.0 || ^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-4.0.2.tgz#bc605eba49ce0fcd598c127fee1c236be3f22918" integrity sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ== -"zod@^3.22.4 || ^4.0.0": - version "4.1.11" - resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.11.tgz#4aab62f76cfd45e6c6166519ba31b2ea019f75f5" - integrity sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg== +"zod@^3.25.0 || ^4.0.0": + version "4.1.12" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.12.tgz#64f1ea53d00eab91853195653b5af9eee68970f0" + integrity sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==