React Native Fix: Could Not Get BatchedBridge and Unable to Resolve Module HTTP, HTTPS, Net, TLS
Fix "Could not get BatchedBridge" and "Unable to resolve module http" errors in React Native. Covers Node.js core module polyfills for HTTP, HTTPS, net, tls, stream, crypto, and fs in Metro bundler for React Native and Expo projects. Updated 2026.
On this page
While building a React Native or Expo app, you may encounter an error saying `Unable to resolve module http` or `Unable to resolve module net` followed by a red screen showing `Could not get BatchedBridge, make sure your bundle is packaged correctly`. This happens when you import a package that depends on Node.js built-in modules like http, https, net, tls, stream, crypto, os, fs, or path. These modules exist in Node.js but do not exist in React Native because React Native runs on JavaScriptCore or Hermes, not Node.js.
The Error
You may also see this for other Node.js core modules: `Unable to resolve module https`, `Unable to resolve module tls`, `Unable to resolve module stream`, `Unable to resolve module crypto`, `Unable to resolve module fs`, `Unable to resolve module os`, `Unable to resolve module path`, `Unable to resolve module zlib`, `Unable to resolve module dns`, or `Unable to resolve module buffer`.
What Causes This Error
React Native uses Metro bundler which runs in a mobile JavaScript environment (Hermes or JavaScriptCore), not Node.js. Node.js has built-in modules like http, net, crypto, and fs that provide system-level functionality. These modules do not exist in React Native because mobile apps cannot open raw TCP sockets, read the file system directly, or create HTTP servers the way Node.js can. When you install a package that was built for Node.js (like a database driver, an SMTP client, or a server-side HTTP library), it tries to import these modules and Metro fails because they do not exist.
- Installed a Node.js server-side package in a React Native project
- Using a package that has separate browser and Node.js entry points but Metro picked the Node.js version
- Directly importing Node.js core modules like http, net, crypto, or fs
- A dependency deep in node_modules imports a Node.js module that the top-level package does not need
- Using a MongoDB, PostgreSQL, or MySQL client library built for Node.js instead of a REST API or mobile SDK
- Using a Node.js SMTP or email library directly in React Native
- Metro config missing browser field resolution that would pick the correct entry point
Fix 1: Use the Correct Package for React Native
The best fix is usually to not polyfill Node.js modules at all. Instead, replace the Node.js package with a React Native compatible alternative. Many packages that work in Node.js have React Native or browser equivalents that use fetch, XMLHttpRequest, or native modules instead of Node.js built-ins.
Common Replacements
- HTTP requests: Use axios or fetch (built into React Native) instead of node-fetch or got
- WebSockets: Use React Native built-in WebSocket API or socket.io-client instead of ws
- Database: Use REST APIs, Supabase client, Firebase SDK, or Expo SQLite instead of mongoose, pg, or mysql2
- Crypto: Use expo-crypto or react-native-crypto instead of Node.js crypto
- JWT: Use jwt-decode to read tokens client-side, verify tokens on your backend server instead
- File system: Use expo-file-system or react-native-fs instead of Node.js fs
- Email: Send emails through your backend API, not directly from the mobile app
Fix 2: Install Node.js Core Module Polyfills
If you must use a package that requires Node.js modules and there is no React Native alternative, you can install polyfills that provide browser-compatible implementations of Node.js built-in modules. This is a workaround, not the ideal solution. Polyfills add bundle size and may not implement every feature of the real Node.js module.
Import the polyfills at the very top of your app entry point, before any other imports.
Fix 3: Configure Metro Resolver for Individual Polyfills
For more control, you can tell Metro to resolve specific Node.js modules to their polyfill packages individually. This is better than a blanket polyfill because you only include what you actually need, keeping your bundle smaller.
You do not need to polyfill every module. Only add entries for the modules that your specific dependency actually uses. Check the error message to see which module is missing and add just that one.
Expo Metro Config Version
Fix 4: Create Empty Module Stubs
Sometimes a dependency imports a Node.js module but never actually calls it in the code path your app uses. For example, a package might conditionally require net only on the server side. In this case, you can create an empty stub file that Metro resolves to instead of the real module. This avoids installing a full polyfill for a module you never use.
Warning: if the dependency actually calls functions from the stubbed module at runtime, your app will crash with `undefined is not a function` or similar errors. Only use stubs for modules that are imported but never called in your code path.
Fix 5: Use the Browser Field in Package.json
Some packages provide both a Node.js and a browser entry point using the `browser` field in their package.json. Metro should pick the browser version automatically, but in some configurations it does not. You can force Metro to prefer the browser field.
Fix 6: Understanding the BatchedBridge Error
The `Could not get BatchedBridge` red screen is not the real error. It is a secondary error that appears because the JavaScript bundle failed to load. When Metro encounters an `Unable to resolve module` error during bundling, it produces a broken bundle. React Native tries to load this bundle, fails to initialize the JS runtime, and shows the BatchedBridge error. To find the real error, check your Metro terminal output. The actual `Unable to resolve module` error will be printed there before the BatchedBridge error appears on the device.
Quick Diagnosis Checklist
- Check Metro terminal output for the real Unable to resolve module error, not the BatchedBridge red screen
- Identify which package is importing the Node.js module from the error path
- Check if a React Native compatible alternative exists before adding polyfills
- If polyfilling: import polyfills at the very top of your entry file before all other imports
- Only polyfill the specific modules your dependency needs, not all Node.js modules
- Use empty stubs for modules that are imported but never called at runtime
- Set resolverMainFields to prefer browser entry points over Node.js entry points
- Clear Metro cache with --reset-cache after changing metro.config.js
- Check if the package has a react-native field in its package.json
- If using a database: connect through a REST API or SDK, not a direct Node.js driver
Common Packages That Cause This Error
Final Working Metro Config
Official-Style Error Explanation
The Unable to resolve module http, net, tls, crypto, or other Node.js built-in module errors occur in React Native because the Metro bundler runs in a mobile JavaScript environment (Hermes or JavaScriptCore) that does not include Node.js built-in modules. When a package designed for Node.js tries to import these modules, Metro cannot find them and the bundle fails. The subsequent Could not get BatchedBridge error is a secondary failure that appears because the broken bundle could not initialize the JavaScript runtime. The fix depends on the situation: replace the Node.js package with a React Native compatible alternative when possible, install polyfill packages that provide browser-compatible implementations of Node.js modules when a replacement does not exist, configure Metro extraNodeModules to map specific modules to their polyfills, or create empty module stubs for modules that are imported but never called at runtime. Always check the Metro terminal output for the real error, not the BatchedBridge red screen on the device.
FAQ
What does Could not get BatchedBridge mean?
BatchedBridge is the communication layer between JavaScript and native code in React Native. The error means the JavaScript bundle failed to load and initialize. It is not the root cause but a symptom. The real error is usually an Unable to resolve module error in the Metro terminal output. Fix the Metro error and the BatchedBridge error goes away.
Why can't I use Node.js modules like http and net in React Native?
React Native runs JavaScript on Hermes or JavaScriptCore, not Node.js. Node.js built-in modules like http, net, tls, and fs are implemented in C++ as part of the Node.js runtime and provide system-level access to networking, file systems, and cryptography. These capabilities do not exist in the mobile JavaScript engine. React Native provides its own networking through fetch and XMLHttpRequest, and file access through native modules like expo-file-system.
Should I polyfill everything or just what I need?
Only polyfill what you need. Each polyfill adds to your JavaScript bundle size and may introduce compatibility issues. Check the error message to identify the exact module that is missing and add only that polyfill. For modules that are imported but never actually called in your code path, use empty stubs instead of full polyfills.
Can I use MongoDB or PostgreSQL directly from React Native?
Not with the standard Node.js drivers like mongoose or pg because they use Node.js net and tls modules for TCP connections. Instead, create a backend API (Express, NestJS, or serverless functions) that connects to your database, and call that API from React Native using fetch or axios. For real-time data, use Firebase Firestore, Supabase, or a WebSocket connection to your backend.
I installed polyfills but still get the error. What is wrong?
Three common causes: polyfills must be imported at the very top of your entry file before any other imports. Metro aggressively caches module resolutions so you must restart with --reset-cache after changing metro.config.js. Some polyfill packages have their own dependencies on other Node.js modules, creating a chain of missing modules that each need to be polyfilled or stubbed.
Is there a single package that polyfills all Node.js modules for React Native?
The node-libs-react-native package provides polyfills for most common Node.js built-in modules. Install it and import node-libs-react-native/globals at the top of your entry file. However, it does not cover every module and some polyfills are incomplete. For production apps, replacing the Node.js package with a React Native alternative is more reliable than polyfilling.
Shahmeer Rizwan
Full-Stack Developer