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
1. `npx create-expo-app myapp`
2. `npm i react-phone-number-input@3.4.12`
3. Import anything from the package, e.g.:
```js
import PhoneInput from 'react-phone-number-input'
```
4. `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`:
```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:
```json
{
"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)
```json
{
"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.
issue