
Security News
Critical Security Vulnerability in React Server Components
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.
babel-preset-expo
Advanced tools
This preset extends the default React Native preset (@react-native/babel-preset) and adds support for tree shaking, bundle splitting, React Server Components, Hermes compilation, advanced dead-code elimination, reanimated, Expo DOM components, server-side rendering, and more...
You can use this preset in any React Native project as a drop-in replacement for @react-native/babel-preset.
If you have problems with the code in this repository, please file issues & bug reports at https://github.com/expo/expo.
A bundler must follow these requirements if they are to be considered spec compliant for use with a universal React (Expo) project.
react-compilerSettings to pass to babel-plugin-react-compiler. Set as false to disable the plugin. As of SDK 51, you must also enable experiments.reactCompiler: true in the app.json.
[
'babel-preset-expo',
{
'react-compiler': {
sources: (filename) => {
// Match file names to include in the React Compiler.
return filename.includes('src/path/to/dir');
},
},
},
];
minifyTypeofWindowSet minifyTypeofWindow: true to transform typeof window checks in your code, e.g. if (typeof window === 'object') -> if (true) in clients. This is useful when you're using libraries that mock the window object on native or in the server.
[
'babel-preset-expo',
{
// If your native app doesn't polyfill `window` then setting this to `false` can reduce bundle size.
native: {
minifyTypeofWindow: true,
},
},
];
Defaults to true for server environments, and false for client environments to support legacy browser polyfills and web workers.
reanimatedboolean, defaults to true. Set reanimated: false to disable adding the react-native-reanimated/plugin when react-native-reanimated is installed.
workletsboolean, boolean, defaults to true. Set worklets: false to disable adding the react-native-worklets/plugin when react-native-worklets is installed. Applies only when using standalone react-native-worklets or react-native-reanimated 4.
jsxRuntimeclassic | automatic, defaults to automatic
automatic automatically convert JSX to JS without the need to import React from 'react' in every file. Be sure to follow the rest of the setup guide after enabling this, otherwise ESLint and other tools will throw warnings.classic does not automatically import anything, React must imported into every file that uses JSX syntax.[
'babel-preset-expo',
{
jsxRuntime: 'classic',
},
];
This property is passed down to @babel/plugin-transform-react-jsx. This flag does nothing when useTransformReactJSXExperimental is set to true because @babel/plugin-transform-react-jsx is omitted.
jsxImportSourcestring, defaults to react
This option allows specifying a custom import source for importing functions.
[
'babel-preset-expo',
{
jsxRuntime: 'automatic',
jsxImportSource: 'react',
},
];
This property is passed down to @babel/plugin-transform-react-jsx. This options does nothing when jsxRuntime is not set to automatic.
lazyImportsChanges Babel's compiled import statements to be lazily evaluated when their imported bindings are used for the first time.
Note: this option has an effect only when the disableImportExportTransform option is set to false. On Android and iOS, disableImportExportTransform defaults to false, and on web it defaults to true to allow for tree shaking.
This can improve the initial load time of your app because evaluating dependencies up front is sometimes entirely un-necessary, particularly when the dependencies have no side effects.
The value of lazyImports has a few possible effects:
null - @react-native/babel-preset will handle it. (Learn more about it here: https://github.com/facebook/metro/commit/23e3503dde5f914f3e642ef214f508d0a699851d)
false - No lazy initialization of any imported module.
true - Lazy-init all imported modules except local imports (e.g., ./foo), certain Expo packages that have side effects, and the two cases mentioned here.
Array<string> - babel-plugin-transform-modules-commonjs will handle it.
(string) => boolean - babel-plugin-transform-modules-commonjs will handle it.
If you choose to do this, you can also access the list of Expo packages that have side effects by using const lazyImportsBlacklist = require('babel-preset-expo/lazy-imports-blacklist'); which returns a Set.
default: null
[
'babel-preset-expo',
{
lazyImports: true
}
],
disableImportExportTransformPass true to disable the transform that converts import/export to module.exports. Avoid setting this property directly. If you're using Metro, set experimentalImportSupport: true instead to ensure the entire pipeline is configured correctly.
// metro.config.js
config.transformer.getTransformOptions = async () => ({
transform: {
// Setting this to `true` will automatically toggle `disableImportExportTransform` in `babel-preset-expo`.
experimentalImportSupport: true,
},
});
If undefined (default), this will be set automatically via caller.supportsStaticESM which is set by the bundler.
[
'babel-preset-expo',
{
disableImportExportTransform: true
}
],
unstable_transformProfileChanges the engine preset in @react-native/babel-preset based on the JavaScript engine that is being targeted. In Expo SDK 50 and greater, this is automatically set based on the jsEngine option in your app.json.
unstable_transformImportMetaEnable that transform that converts import.meta to globalThis.__ExpoImportMetaRegistry, defaults to false in client bundles and true for server bundles.
Note: Use this option at your own risk. If the JavaScript engine supports
import.metanatively, this transformation may interfere with the native implementation.
enableBabelRuntimePassed to @react-native/babel-preset.
disableFlowStripTypesTransformPassed to @react-native/babel-preset.
All options can be passed in the platform-specific objects native and web to provide different settings on different platforms. For example, if you'd like to only apply disableImportExportTransform on web, use the following:
[
'babel-preset-expo',
{
// Default value:
disableImportExportTransform: false,
web: {
// Web-specific value:
disableImportExportTransform: true,
},
},
];
Platform-specific options have higher priority over top-level options.
The Babel loading mechanism must include the following properties on its caller.
A platform property denoting the target platform. If the platform is not defined, it will default to using web when the bundler is webpack -- this is temporary and will throw an error in the future.
| Value | Description |
|---|---|
ios | Runs on iOS devices |
android | Runs on Android devices |
web | Runs in web browsers |
A bundler property denoting the name of the bundler that is being used to create the JavaScript bundle.
If the bundler is not defined, it will default to checking if a babel-loader is used, if so then webpack will be used, otherwise it will default to metro.
| Value | Description |
|---|---|
metro | Bundling with Metro |
webpack | Bundling with Webpack |
babel-preset-react-native is a Babel preset specifically designed for React Native projects. It includes a set of Babel plugins and configurations optimized for React Native development. While it is similar to babel-preset-expo, it does not include Expo-specific configurations and optimizations.
babel-preset-env is a Babel preset that allows you to use the latest JavaScript features without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). It is more general-purpose compared to babel-preset-expo, which is tailored for Expo projects.
babel-preset-stage-3 is a Babel preset that includes plugins for stage 3 proposals of ECMAScript. It allows you to use experimental JavaScript features that are close to being finalized. While it provides cutting-edge features, it is not specifically optimized for React Native or Expo projects like babel-preset-expo.
FAQs
The Babel preset for Expo projects
The npm package babel-preset-expo receives a total of 1,833,803 weekly downloads. As such, babel-preset-expo popularity was classified as popular.
We found that babel-preset-expo demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 11 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.

Research
/Security News
We spotted a wave of auto-generated “elf-*” npm packages published every two minutes from new accounts, with simple malware variants and early takedowns underway.

Security News
TypeScript 6.0 will be the last JavaScript-based major release, as the project shifts to the TypeScript 7 native toolchain with major build speedups.