SDK40 Update - can't resolve any modules / imports (jsx)

Please provide the following:

  1. SDK Version: 40
  2. Platforms(Android/iOS/web/all): iOS

I have a very weird problem, once upgrading to SDK 40 when I try to start the app in the iOS simulator the build fails with the error:

Failed building JavaScript bundle.
Unable to resolve "./src/auth_gate" from "App.js"

That is, the main App.js which is the entrypoint somehow can’t resolve the first import - “auth_gate.jsx” that is in ./src. When I navigate the folders I can see that it is there, if I roll back to SDK 39 (git reset) then it works all fine.

I tried to clear expo start -c, watchman watch-del-all and remove and reinstall the node_modules. Any other ideas?

When I remove the import in App.js, it just goes to the next import and says it can’t find it - so seems like somehow it can’t “see” that the files are where I specify them to be… hope I make sense and thank you all for any help with this!

App.js code snippet:

import Auth from "./src/auth_gate";

export default function App() {
  const isReadyRef = useRef(null);
  const navigationRef = useRef(null);

auth_gate.jsx snippet:

export default function Auth() {
  const [loading, setLoading] = useState(true);

Ok, I have done some more debugging here and for some reason my metro.config.js doesn’t include the .jsx as it did in SDK39. When I manually put “jsx” into sourceExts below, just after “svg” in the array, then the modules can be loaded correctly. HOWEVER, then I get a AsyncStorage is null error (see


I add in my app.json, metro.config.js and expo diagnostics as I hope someone can help me with this. It looks like something goes wrong when I do expo upgrade and move from SDK 39 to 40. I have tried to:

  1. Update expo-cli, I should be on the latest version 4.0.13
  2. Switch to the new asyncstorage as specified by the docs (LINK)
  3. Cleared cache (expo start -c)
  4. Added in the “jsx” in the below metro.config.js directly but then AsyncStorage crashes
  5. Started fresh from SDK39 and doing it all again, after clearing watchman.

Nothing has worked so far…


  "expo": {
    "name": "xxx",
    "slug": "xxx",
    "scheme": "xxx",
    "platforms": ["ios", "android", "web"],
    "version": "0.2.4",
    "orientation": "default",
    "icon": "./assets/logo.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#000000"
    "notification": {
      "icon": "./assets/notification_icon.png",
      "color": "#ffffff",
      "androidMode": "default",
      "androidCollapsedTitle": "xxx"
    "updates": {
      "enabled": true,
      "fallbackToCacheTimeout": 45000
    "assetBundlePatterns": ["assets/*"],
    "ios": {
      "bundleIdentifier": "xxx",
      "supportsTablet": true,
      "buildNumber": "0.2.4",
      "config": {
        "branch": {
          "apiKey": "xxx"
    "android": {
      "package": "xxx",
      "versionCode": 24,
      "googleServicesFile": "./google-services.json",
      "useNextNotificationsApi": true,
      "adaptiveIcon": {
        "foregroundImage": "./assets/androidicon.png"
      "config": {
        "branch": {
          "apiKey": "xxx"
      "permissions": [
    "packagerOpts": {
      "config": "metro.config.js",
      "sourceExts": [
    "hooks": {
      "postPublish": [
          "file": "sentry-expo/upload-sourcemaps",
          "config": {
            "organization": "xxx",
            "project": "react-native-mobile-app",
            "authToken": "xxx"

metro.config.js (NOTE: I added in “jsx” after “svg” in sourceExts array, this allows for the Auth function to be loaded but then AsyncStorage crashes, see red screenshot error above):

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();

  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer"),
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== "svg"),
      sourceExts: [...sourceExts, "svg", "jsx"],

expo diagnostics:

  Expo CLI 4.0.13 environment info:
      OS: macOS 10.15.7
      Shell: 5.7.1 - /bin/zsh
      Node: 14.6.0 - /usr/local/bin/node
      npm: 6.14.9 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
      iOS SDK:
        Platforms: iOS 14.2, DriverKit 20.0, macOS 11.0, tvOS 14.2, watchOS 7.1
      Android Studio: 4.0 AI-193.6911.18.40.6626763
      Xcode: 12.2/12B45b - /usr/bin/xcodebuild
      @expo/webpack-config: ~0.12.45 => 0.12.51 
      expo: ^40.0.0 => 40.0.0 
      react: 16.13.1 => 16.13.1 
      react-dom: 16.13.1 => 16.13.1 
      react-native: => 0.63.2 
      react-native-web: ~0.13.12 => 0.13.18 
      react-navigation: ^4.4.1 => 4.4.3 
      expo-cli: 4.0.13
    Expo Workflow: managed

For the people coming after me, I solved this through a github issue that @notbrent already answered (thank you!!).

Find it here: Migration from SDK 37 to 40 · Issue #11314 · expo/expo · GitHub

And a working metro.config.js can be found here: Expo bundling fixes · dooboolab/hackatalk@2e45ee5 · GitHub

Note the “const { getDefaultConfig } = require(‘@expo/metro-config’);”, I was importing the standard metro-config and not the @expo one. Once I changed my metro.config.js to reflect what is in the link above SDK 40 works like a charm!

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.