v4: Error - "Cannot call a class as a function" in React Native.
Building a schema with zod v4 (for example simply const str = z.string(), any schema construction method will cause the error) in an Expo project throws a "Cannot call a class as a function" error.
I was able to confirm a minimal repro by using npx create-expo-app@latest, adding zod v4, and adding the above string parse line to the home component function body, and nothing else.
There's no indication of deeper error source. No linter error occurs, and it's such a basic functionality that I know works in other environments I suspect something fishy is happening with the Metro bundling process and the $constructor function from @zod/core.
This seems like a dual package hazard issue, and since RN 0.79 the unstable_enablePackageExports option is enable by default https://github.com/facebook/metro/pull/1448.
I created a repro with Expo SDK 53, which came with RN 0.79. As soon as you import zod, it starts throwing the error. If you try to opt-out of unstable_enablePackageExports, it will not be able to resolve some of the modules.
https://github.com/chungweileong94/RN-zod-v4-bug
Is there any progress or other workarounds for this? We're also seeing this issue and I'm surprised no one else is hitting it with React Native.
Is there any progress or other workarounds for this? We're also seeing this issue and I'm surprised no one else is hitting it with React Native.
So far based on what I'm noticing is that you will hit the (similar) issue if you are using:
- Zod v3 + RN with
unstable_enablePackageExports - Zod v4 + RN
Both of these combinations are considered pretty new, unstable_enablePackageExports only got enabled by default in the recent RN/Expo release, and usually RN dev don't upgrade that often, so it makes sense that not many people are hitting this issue just yet. As for Zod v4, it's betaπ€·
For now, my workaround is to stay on Zod v3, and make sure the unstable_enablePackageExports is off.
I'm also experiencing this. I tried several combinations of package exports but none of them seemed to resolve my issue. I tried:
- Adding a
react-nativeexport key for all fields to the commonjs build - Removing all the export keys to force it to go to commonjs
config.resolver.unstable_enablePackageExports = falsereveals there is an issue with parsing@zod/core.- I also tried an option where I resolved only the source development build, but the
.jsextensions in the the source files in@zod/corecould not be resolved by Metro.
facing the same issue. It only happens at ios and android though. web build won't have this issue
This is not fixed yet with the new zod/v4 package.
Has anyone managed to get round it?
@colinhacks any chance to look on this; please
I'm having this same issue in a regular react/webpack/typescript project, with no metro/RN/hermes stuff... can anyone point me in the right direction for where to start debugging my config?
or should I be waiting for the RN fix and hoping it helps?
edit: looked a bit closer and noticed it reproduces in the most simple react/ts template i could find, so i guess there's probably nothing specific to RN here (though i'm guessing that also means that work towards fixing RN will also fix other uses)
using [email protected] solved the issue for me.
Landed in stable: [email protected]
I encountered the "Cannot call a class as a function" error in my React Native project, and after investigation, I found the root cause was an import conflict between React Native's Text component and SVG's Text component.
The Problem In my StepCounter.tsx file, I was using the Text component without properly importing it from react-native:
// β WRONG - Missing Text import
import { View } from "react-native";
// Later in the component:
<Text style={{...}}>Some text</Text> // This caused the error!
Meanwhile, my ProgressRingDisplay.tsx file had both imports:
// β
CORRECT - Both imports present
import { View, Text } from "react-native";
import Svg, { Text as SvgText, G, Path, ... } from "react-native-svg";
Why This Happens When you don't explicitly import Text from react-native but you have SVG components in your component tree (either directly or through child components), React Native's bundler can get confused about which Text component to use. The SVG Text component is a class-based component meant for SVG rendering, while React Native's Text is a function component for regular text display.
Trying to use the SVG Text component as a regular text component results in the "Cannot call a class as a function" error because the bundler attempts to call the SVG Text class as if it were a function component.
The Solution Simply add Text to your React Native imports:
// β
FIXED
import { View, Text } from "react-native";
Key Takeaways
- Always explicitly import components you use, even if they seem to work without imports initially
- Watch out for naming conflicts between different libraries (react-native vs react-native-svg)
- This error can be misleading - it's not always about calling classes as functions, but often about import resolution conflicts
- Check your imports first when encountering this error, especially in projects mixing different UI libraries
When This Might Happen to You
- Mixing react-native and react-native-svg components
- Using components without proper imports in complex component hierarchies
- Working with any libraries that have overlapping component names
- Metro bundler resolving imports differently than expected
This issue is different from the Zod v4 React Native compatibility issues that others have reported - it's specifically about import conflicts within your own codebase.
I encountered the "Cannot call a class as a function" error in my React Native project, and after investigation, I found the root cause was an import conflict between React Native's Text component and SVG's Text component.
The Problem In my StepCounter.tsx file, I was using the Text component without properly importing it from react-native:
// β WRONG - Missing Text import import { View } from "react-native"; // Later in the component: <Text style={{...}}>Some text</Text> // This caused the error!Meanwhile, my ProgressRingDisplay.tsx file had both imports:
// β CORRECT - Both imports present import { View, Text } from "react-native"; import Svg, { Text as SvgText, G, Path, ... } from "react-native-svg";Why This Happens When you don't explicitly import Text from react-native but you have SVG components in your component tree (either directly or through child components), React Native's bundler can get confused about which Text component to use. The SVG Text component is a class-based component meant for SVG rendering, while React Native's Text is a function component for regular text display.
Trying to use the SVG Text component as a regular text component results in the "Cannot call a class as a function" error because the bundler attempts to call the SVG Text class as if it were a function component.
The Solution Simply add Text to your React Native imports:
// β FIXED import { View, Text } from "react-native";Key Takeaways
- Always explicitly import components you use, even if they seem to work without imports initially
- Watch out for naming conflicts between different libraries (react-native vs react-native-svg)
- This error can be misleading - it's not always about calling classes as functions, but often about import resolution conflicts
- Check your imports first when encountering this error, especially in projects mixing different UI libraries
When This Might Happen to You
- Mixing react-native and react-native-svg components
- Using components without proper imports in complex component hierarchies
- Working with any libraries that have overlapping component names
- Metro bundler resolving imports differently than expected
This issue is different from the Zod v4 React Native compatibility issues that others have reported - it's specifically about import conflicts within your own codebase.
This help .Thanks