Expo/Metro warning: invalid exports in libphonenumber-js/min/metadata (targets must start with "./")
What happened
When running an Expo app that depends on react-phone-number-input@3.4.12 (which uses libphonenumber-js), Metro prints this warning:
WARN The package <MY_APP_ROOT>/node_modules/libphonenumber-js/min/metadata contains an invalid package.json configuration. Consider raising this issue with the package maintainer(s). Reason: One or more mappings for subpaths defined in "exports" are invalid. All values must begin with "./". Falling back to file-based resolution.
The app continues to work, but the warning appears on every cold start.
Repro steps
npx create-expo-app myappnpm i react-phone-number-input@3.4.12- Import anything from the package, e.g.:
import PhoneInput from 'react-phone-number-input' -
npx expo start→ open the app and observe the Metro warning above.
Environment
- Expo (SDK 53+)
- Metro (package exports enabled)
- Platforms: iOS / Android / Web (warning is shown in Metro logs)
-
react-phone-number-input: 3.4.12 -
libphonenumber-js: as installed via the dependency above
Why this happens
libphonenumber-js includes a nested package at min/metadata whose package.json contains exports mappings that point outside that subpackage via ../../.... Per Node’s package exports rules, export targets must be relative paths that start with "./" (and must not traverse up with ..). Metro enforces this, warns, and then falls back to legacy file-based resolution so the app still runs.
An example of the problematic mapping in min/metadata/package.json:
{
"exports": {
".": {
"types": "../../metadata.min.json.d.ts",
"import": "../../metadata.min.json.js",
"require": "../../metadata.min.json"
}
}
}
Because the subpackage root is min/metadata/, those ../../ targets violate the "./" requirement.
Suggested fixes
Any of the following would remove the warning and make the package spec-compliant:
-
Option A (preferred): Expose metadata via the root package’s exports without a nested subpackage:
{ "name": "libphonenumber-js", "exports": { "./min/metadata": { "types": "./metadata.min.json.d.ts", "import": "./metadata.min.json.js", "require": "./metadata.min.json" } // Optionally the same for: ./max/metadata, ./mobile/metadata } } -
Option B: Keep the nested min/metadata package, but make its files local and its exports targets start with "./" (would require duplicating or moving the files into that folder)
{ "name": "libphonenumber-js/min/metadata", "exports": { ".": { "types": "./metadata.min.json.d.ts", "import": "./metadata.min.json.js", "require": "./metadata.min.json" } } }
References
- Node.js docs on "exports" target formats (targets must start with ./): https://nodejs.org/api/packages.html#exports
- Metro package exports background (warning & fallback behavior): https://metrobundler.dev/docs/configuration/#unstable_enablepackageexports-experimental
Thanks for taking a look! I’m happy to test a prerelease or proposed fix.