supabase-js
supabase-js copied to clipboard
Can't use with unstable_enablePackageExports metro option (expo)
Cross-posting https://github.com/supabase/realtime-js/issues/415 because I'm not sure you're monitoring the issues on the other repo :)
Bug report
- [x] I confirm this is a bug with Supabase, not with my own application.
- [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
When using @supabase/supabase-js in an expo react native project, if I use the unstable_enablePackageExports with the metro bundler, bundling fails with the following error:
To Reproduce
- Generate a new expo app
- Add
@supabase/supabase-jsas a dependency - Create a supabase client in the main
_layout.tsxfile - Run
npx expo customize metro.config.js - Add
config.resolver.unstable_enablePackageExports = true;tometro.config.js - Add
ios.bundleIdentifiertoapp.json - Run
npx expo run:ios
Repro repo: https://github.com/aldebout/supabase-expo-exports-issue
Expected behavior
No crash
Screenshots
System information
- OS: macOS
- Version of supabase-js: 2.45.1
- Version of Node.js: 20.16.0
Additional information
Opening here because the error message I got in my actual project was
The package at "../../node_modules/@supabase/realtime-js/node_modules/ws/lib/stream.js" attempted to import the Node standard library module "stream".
It failed because the native React runtime does not include the Node standard library.
Is there any update on this? I've run into the same issue
I've also run into this when trying to use Storybook and Expo.
I'm able to run it by manually specifying nodeModulesPaths and setting disableHierarchicalLookup to true (in a monorepo setup).
I'm able to run it by manually specifying nodeModulesPaths and setting disableHierarchicalLookup to true (in a monorepo setup).
This solution didn't work for me
I was able to fix it by patching @supabase/realtime-js to match supabase/realtime-js#426
patchfile looks like this
diff --git a/dist/module/RealtimeClient.js b/dist/module/RealtimeClient.js
index a8bb0121343481d789acb0248ecbb20c7e4597fe..a299d5b3370b836bdf28307deb7a157c6ccf0bc5 100644
--- a/dist/module/RealtimeClient.js
+++ b/dist/module/RealtimeClient.js
@@ -143,12 +143,6 @@ export default class RealtimeClient {
this.conn = null;
},
});
- import('ws').then(({ default: WS }) => {
- this.conn = new WS(this._endPointURL(), undefined, {
- headers: this.headers,
- });
- this.setupConnection();
- });
}
/**
* Disconnects the socket.
named patches/@supabase__realtime-js.patch
I then added the following to my package.json (for pnpm)
"pnpm": {
"patchedDependencies": {
"@supabase/realtime-js": "patches/@supabase__realtime-js.patch"
},
"overrides": {
"@supabase/realtime-js>ws": "-"
}
}
I've merged https://github.com/supabase/realtime-js/pull/444 so 2.11.4-next.1 will have this code.
I do need some help testing this change, if possible do override realtime-js in supabase-js with this version
Unfortunately doesn't seem to be working
Can also confirm that the package is overriden correctly
so this is happening during the bundling process of Expo, is there a way to configure which package to remove from the bundling process in some sort of configuration?
Not sure about expo but with pnpm I can do this and it works
"pnpm": {
"overrides": {
"@supabase/realtime-js": "2.11.4-next.1",
"@supabase/realtime-js>ws": "-"
}
}
I need to double check why we need the ws library 🤔
Same issue here.
ERROR [Error: undefined Unable to resolve module stream from /Users/gianpaj/tmp/call-me-please/node_modules/ws/lib/stream.js: stream could not be found within the project or in these directories:
../../node_modules
../../../node_modules
node_modules
../../node_modules
1 | 'use strict';
2 |
> 3 | const { Duplex } = require('stream');
| ^
4 |
5 | /**
6 | * Emits the `'close'` event on a stream.]
The package at "node_modules/ws/lib/stream.js" attempted to import the Node standard library module "stream".
It failed because the native React runtime does not include the Node standard library.
the code is open sourced here: https://github.com/gianpaj/call-me-please
If you uncomment the supabase import and the Signup <Button/> in the settings.tsx file, you'll see the same error message
$ pnpm list --depth 1 | grep supabase
@supabase/supabase-js 2.47.10
├── @supabase/auth-js 2.67.3
├── @supabase/functions-js 2.4.4
├── @supabase/node-fetch 2.6.15
├── @supabase/postgrest-js 1.17.7
├── @supabase/realtime-js 2.11.2
└── @supabase/storage-js 2.7.1
$ pnpm list --depth 0 | grep expo
@expo/metro-config 0.19.8
expo 52.0.23
Overwriting to 2.11.4-next.1 of @supabase/realtime-js didn't work either :(
This is the metro.config.js file for Turborepo mono repo setup
https://github.com/gianpaj/call-me-please/blob/master/apps/expo/metro.config.js
Any update? I can't get past this issue as other parts of my project need unstable_enablePackageExports: true.
@filipecabaco any updates?
Has it been solved? couldnt find anything
not yet unfortunately as removing ws package has proven not to be enough ... any other clue on what it could help?
So far the only thing that worked was setting unstable_enablePackageExports to false, though i dont know what consequences it could have on my project. Im currently using create-t3-turbo but with expo 52, and it got it to work but now nativewind has broken.
So far the only thing that worked was setting unstable_enablePackageExports to false, though i dont know what consequences it could have on my project. Im currently using create-t3-turbo but with expo 52, and it got it to work but now nativewind has broken.
Doing this in a monorepo breaks the import of packages in the monorepo: Unable to resolve "@acme/shared/utils" from "apps/expo/src/app/profile.tsx"
For the tailwind thing probably just update it, also update the react-native-css-interop package.
I've tried everything mentioned in here but haven't figured how to make it work. I've got another repo where its working but its much simpler, haven't figured out what breaks it as both are based on the create-t3-turbo example
So far the only thing that worked was setting unstable_enablePackageExports to false, though i dont know what consequences it could have on my project. Im currently using create-t3-turbo but with expo 52, and it got it to work but now nativewind has broken.
Doing this in a monorepo breaks the import of packages in the monorepo:
Unable to resolve "@acme/shared/utils" from "apps/expo/src/app/profile.tsx"For the tailwind thing probably just update it, also update the
react-native-css-interoppackage.I've tried everything mentioned in here but haven't figured how to make it work. I've got another repo where its working but its much simpler, haven't figured out what breaks it as both are based on the
create-t3-turboexample
I have updates regarding the nativewind issue. Turns out it was another dependecy called react native reusables which created a tailwind.config.js file when the monorepo already uses a tailwind.config.ts file on apps/expo, so its was just a matter of merging those configs and it worked.
On the other hand, i unfortunately had to uninstall supabase since expo 52 wont compile at all. Have you tried cloning a fresh copy of create-t3-turbo (Julius just updated some packages like expo and more recently) and installing just supabase to see if it even runs? i swear, nextauth is just the worst thing ever even if somehow you manage to get it working, it just finds a way to f with you every time. Im desperate to try supabase auth on my app.
To be fair, when i set unstable_enablePackageExports to false it did not cause the Unable to resolve "@acme/shared/utils" from "apps/expo/src/app/profile.tsx" you mention. It may do so after u get past the supabase error, i dont really know though. I found some other metro config you could pull to allow expo to manually (as in, you have to write the aliases for each one u want) access your monorepo packages, which i alledge would fix your issue.
New update: I got it to work out of the box!
Clone the latest version of create-t3-turbo, follow the tutorial at https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native?queryGroups=auth-store&auth-store=async-storage to do the supabase setup and it'll work. Tried it twice and no metro issues, no nothing and without having to set unstable_enablePackageExports to false
Just in case do a pnpm dlx expo prebuild --clean first then pnpm ios or pnpm android . I'd also advise you make sure to edit the start script as follows "dev": "expo start --clear" so you dont run into cache issues.
So far i've only tried supabase auth but will update this when i try realtime and other supabase products.
If you dont work in a monorepo you can just follow how expo is set up at apps/expo and it'll work too.
New update: I got it to work out of the box!
Clone the latest version of create-t3-turbo, follow the tutorial at https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native?queryGroups=auth-store&auth-store=async-storage to do the supabase setup and it'll work. Tried it twice and no metro issues, no nothing and without having to set unstable_enablePackageExports to false
Just in case do a
pnpm dlx expo prebuild --cleanfirst thenpnpm iosorpnpm android. I'd also advise you make sure to edit the start script as follows"dev": "expo start --clear"so you dont run into cache issues.So far i've only tried supabase auth but will update this when i try realtime and other supabase products.
If you dont work in a monorepo you can just follow how expo is set up at apps/expo and it'll work too.
This didn't work out for me, tried it by cloning it and following the guide you provided and haven't been able to get it working.
This fixed the issues I've been having:
config.resolver.unstable_conditionNames = ['require', 'default', 'browser']. For me, adding 'browser' has fixed it so far.
Sorry for the radio silence on my side.
@IamJoshing is there a explicit explanation why this works? it could help us understand what we need to change in realtime-js to properly fix it.
I have no idea. I tried it after everything else had failed. I found some other examples of metro configs on the Expo Discord with more condition names. I added in the condition names that I didn't have. It worked. Then I removed them individually until I knew it was 'browser'. If this works for others, maybe someone at Expo can give you an answer as to why.
I have no idea. I tried it after everything else had failed. I found some other examples of metro configs on the Expo Discord with more condition names. I added in the condition names that I didn't have. It worked. Then I removed them individually until I knew it was 'browser'. If this works for others, maybe someone at Expo can give you an answer as to why.
Yes, that's correct. Just wanted to confirm this works and send a snippet to fix it here.
// metro.config.js
const config = {
resolver: {
unstable_conditionNames: ['browser'],
unstable_enablePackageExports: false,
}
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
Just stumbled upon this as was facing this issue (using SDK 53 beta). This behavior is expected: Metro’s support for Node‑style conditional exports now strictly honors the configured “conditions” (require, import, etc.) when resolving a package’s exports field, and it will only consider the "browser" entry if you explicitly include "browser" in its condition list.
This change comes from Metro bundler and mentioned as a breaking change https://expo.dev/changelog/sdk-53-beta. Also mentions setting unstable_enablePackageExports: false.
I have no idea. I tried it after everything else had failed. I found some other examples of metro configs on the Expo Discord with more condition names. I added in the condition names that I didn't have. It worked. Then I removed them individually until I knew it was 'browser'. If this works for others, maybe someone at Expo can give you an answer as to why.
Yes, that's correct. Just wanted to confirm this works and send a snippet to fix it here.
// metro.config.js const config = { resolver: { unstable_conditionNames: ['browser'], unstable_enablePackageExports: false, } };
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
you saved me, thanks a lot!!
I just came here for Expo SDK 53 + Supabase combo and want to confirm this works:
Yes, that's correct. Just wanted to confirm this works and send a snippet to fix it here.
// metro.config.js const config = { resolver: { unstable_conditionNames: ['browser'], unstable_enablePackageExports: false, } };
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
Although I rewrote it as:
// Expo SDK 53 + Supabase
config.resolver.unstable_conditionNames = ['browser']
config.resolver.unstable_enablePackageExports = false
is there any solution about this bug???
I can't disable package exports since I use this feature in my mono-repo project, instead, I added this config:
// metro.config.js
const config = {
resolver: {
resolveRequest: (context, moduleName, platform) => {
if (moduleName === "ws") {
return { type: "empty" };
}
return context.resolveRequest(context, moduleName, platform);
},
},
}
we're releasing a next version of supabase-js to try and test out if a fix works: https://github.com/supabase/supabase-js/pull/1395
The issue seems to be fixed in the latest version as reported by users, so I am closing this issue. If issue persists, please feel free to tag me here, or create a new issue. Thank you everyone!