TypeScript icon, indicating that this package has built-in type declarations

10.0.1 • Public • Published


This preset extends the default React Native preset (@react-native/babel-preset) and adds support for decorators, tree-shaking web packages, and loading font icons with optional native dependencies if they're installed.

You can use this preset in any React Native project as a drop-in replacement for @react-native/babel-preset. If your project isn't using native font loading or web support then this preset will only add support for decorators with @babel/plugin-proposal-decorators - this is mostly used for supporting legacy community libraries.

If you start your web project with @expo/webpack-config or npx expo start and your project doesn't contain a babel.config.js or a .babelrc then it will default to using babel-preset-expo for loading.

If you have problems with the code in this repository, please file issues & bug reports at Thanks!

Expo Bundler Spec Compliance

A bundler must follow these requirements if they are to be considered spec compliant for use with a universal React (Expo) project.

Babel Loader

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



boolean, defaults to true. Set reanimated: false to disable adding the react-native-reanimated/plugin when react-native-reanimated is installed.


classic | 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.
    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.


string, defaults to react

This option allows specifying a custom import source for importing functions.

    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.


Changes 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:

default: null

        lazyImports: true


Pass 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.

        disableImportExportTransform: true


Changes 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.


Passed to @react-native/babel-preset.


Passed to @react-native/babel-preset.

Platform-specific options

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:

    // Default value:
    disableImportExportTransform: false,

    web: {
      // Web-specific value:
      disableImportExportTransform: true,

Platform-specific options have higher priority over top-level options.

Package Sidebar


npm i babel-preset-expo

Weekly Downloads






Unpacked Size

40.4 kB

Total Files


Last publish


  • radoslawkrzemien
  • pkham
  • szdziedzic
  • tsapeta
  • wkozyra
  • ide
  • lukmccall
  • alanhughes
  • kadikraman
  • aleqsio
  • marklawlor
  • gabrieldonadel
  • simek
  • keith-kurak
  • christopherwalter
  • kbrandwijk
  • fiber-god
  • brentvatne
  • evanbacon
  • quinlanj
  • expoadmin
  • exponent
  • wschurman
  • bycedric
  • jonsamp
  • princefleaswallow
  • kudochien