A Babel plugin that transforms React Native imports to react-native-web direct module paths, enabling tree-shaking and bundle size optimization for web applications using React Native components.
npm install --save-dev babel-plugin-react-native-webThis package is used as a Babel plugin, not imported directly in code:
.babelrc configuration:
{
"plugins": [
["react-native-web", { "commonjs": true }]
]
}babel.config.js configuration:
module.exports = {
plugins: [
["babel-plugin-react-native-web", { commonjs: false }]
]
};The plugin automatically transforms React Native imports during the build process:
Input code:
import { StyleSheet, View, Text } from 'react-native';
import React from 'react';
const App = () => (
<View style={styles.container}>
<Text>Hello World</Text>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1 }
});Output after transformation (ES modules):
import StyleSheet from 'react-native-web/dist/exports/StyleSheet';
import View from 'react-native-web/dist/exports/View';
import Text from 'react-native-web/dist/exports/Text';
import React from 'react';
// Component code remains unchangedOutput after transformation (CommonJS):
import StyleSheet from 'react-native-web/dist/cjs/exports/StyleSheet';
import View from 'react-native-web/dist/cjs/exports/View';
import Text from 'react-native-web/dist/cjs/exports/Text';
import React from 'react';
// Component code remains unchangedThe main export is a Babel plugin factory function that returns a plugin configuration.
/**
* Babel plugin factory function
* @param {Object} babel - Babel instance with types
* @param {Object} babel.types - Babel types (t)
* @returns {Object} Babel plugin configuration
*/
function babelPluginReactNativeWeb({ types: t }) {
return {
name: 'Rewrite react-native to react-native-web',
visitor: {
ImportDeclaration(path, state) {
// Transforms import statements from react-native/react-native-web to direct module paths
},
ExportNamedDeclaration(path, state) {
// Transforms export statements from react-native/react-native-web to direct module paths
},
VariableDeclaration(path, state) {
// Transforms CommonJS require() calls from react-native/react-native-web to direct module paths
}
}
};
}Configuration options that can be passed to the plugin.
interface PluginOptions {
/**
* Output format control - when true, transforms imports to point to CommonJS modules
* @default false
*/
commonjs?: boolean;
}Transforms ES6 import statements from react-native to react-native-web paths.
Supported import patterns:
// Named imports - transformed to separate default imports
import { View, Text, StyleSheet } from 'react-native';
// Becomes:
// import View from 'react-native-web/dist/exports/View';
// import Text from 'react-native-web/dist/exports/Text';
// import StyleSheet from 'react-native-web/dist/exports/StyleSheet';
// Default import - transformed to index import
import ReactNative from 'react-native';
// Becomes: import ReactNative from 'react-native-web/dist/index';
// Namespace import - transformed to index import
import * as RN from 'react-native';
// Becomes: import * as RN from 'react-native-web/dist/index';
// Aliased imports - preserves local names
import { View as MyView, Text as MyText } from 'react-native';
// Becomes:
// import MyView from 'react-native-web/dist/exports/View';
// import MyText from 'react-native-web/dist/exports/Text';Transforms ES6 re-exports from react-native to react-native-web paths.
Supported export patterns:
// Named re-exports
export { View, Text } from 'react-native';
// Becomes:
// export { default as View } from 'react-native-web/dist/exports/View';
// export { default as Text } from 'react-native-web/dist/exports/Text';
// Aliased re-exports
export { View as MyView } from 'react-native';
// Becomes: export { default as MyView } from 'react-native-web/dist/exports/View';Transforms CommonJS require() calls from react-native to react-native-web paths.
Supported require patterns:
// Destructured require
const { View, Text } = require('react-native');
// Becomes:
// const View = require('react-native-web/dist/exports/View').default;
// const Text = require('react-native-web/dist/exports/Text').default;
// Default require
const ReactNative = require('react-native');
// Becomes: const ReactNative = require('react-native-web/dist/index');Special handling for specific React Native APIs.
// unstable_createElement is mapped to createElement
import { unstable_createElement } from 'react-native';
// Becomes: import unstable_createElement from 'react-native-web/dist/exports/createElement';
// react-native-web imports are also transformed (for consistency)
import { View } from 'react-native-web';
// Becomes: import View from 'react-native-web/dist/exports/View';All React Native components and APIs supported by react-native-web are transformed:
// UI Components
AccessibilityInfo, ActivityIndicator, Alert, Animated, AppRegistry, AppState,
Appearance, BackHandler, Button, CheckBox, Clipboard, DeviceEventEmitter,
Dimensions, Easing, FlatList, I18nManager, Image, ImageBackground,
InputAccessoryView, InteractionManager, Keyboard, KeyboardAvoidingView,
LayoutAnimation, Linking, LogBox, Modal, NativeEventEmitter, NativeModules,
PanResponder, Picker, PixelRatio, Platform, Pressable, ProgressBar,
RefreshControl, SafeAreaView, ScrollView, SectionList, Share, StatusBar,
StyleSheet, Switch, Text, TextInput, Touchable, TouchableHighlight,
TouchableNativeFeedback, TouchableOpacity, TouchableWithoutFeedback,
UIManager, Vibration, View, VirtualizedList, YellowBox
// Utilities
createElement, findNodeHandle, processColor, render, unmountComponentAtNode
// Hooks
useColorScheme, useLocaleContext, useWindowDimensionsThe plugin performs AST transformations and does not throw runtime errors. Build-time issues may occur if:
Ensure react-native-web is installed as a dependency when using this plugin, as the transformed imports will reference react-native-web modules.
Webpack configuration with Babel:
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
use: {
loader: 'babel-loader',
options: {
plugins: [
['babel-plugin-react-native-web', { commonjs: false }]
]
}
}
}
]
}
};Next.js configuration:
// next.config.js
module.exports = {
webpack: (config) => {
config.module.rules.push({
test: /\.(js|jsx|ts|tsx)$/,
use: {
loader: 'babel-loader',
options: {
plugins: [
['babel-plugin-react-native-web', { commonjs: false }]
]
}
}
});
return config;
}
};