# babel-preset-expo

> The Babel preset for Expo projects

Latest version **57.0.12** (published 2026-09-15) · MIT license · 0 weekly downloads

## Install

```sh
npm install babel-preset-expo
pnpm add babel-preset-expo
yarn add babel-preset-expo
bun add babel-preset-expo
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; no vulnerabilities; recently updated; high maintenance score; high quality score; popular repo; extremely popular.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 57.0.12 |
| Published | 2026-09-15 |
| First published | 2017-03-03 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 42 |
| Unpacked size | 303.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 52209 |
| Author | Expo |
| Maintainers | ide, brentvatne, expoadmin, exponent, bycedric, kudochien, alanhughes, tsapeta, expo-bot, philpl, ccheever, wschurman |
| Keywords | babel, babel-preset, expo, expo-web, react-native, react-native-web, metro, webpack |

## Links

- npm: https://www.npmjs.com/package/babel-preset-expo
- Repository: https://github.com/expo/expo
- Homepage: https://github.com/expo/expo/tree/main/packages/babel-preset-expo#readme
- Issues: https://github.com/expo/expo/issues
- npm.io page: https://npm.io/package/babel-preset-expo

## Dependencies (42)

- [debug](https://npm.io/package/debug.md) ^4.3.4
- [@babel/generator](https://npm.io/package/@babel/generator.md) ^7.20.5
- [@babel/preset-typescript](https://npm.io/package/@babel/preset-typescript.md) ^7.23.0
- [babel-plugin-react-compiler](https://npm.io/package/babel-plugin-react-compiler.md) ^1.0.0
- [@babel/helper-module-imports](https://npm.io/package/@babel/helper-module-imports.md) ^7.25.9
- [babel-plugin-react-native-web](https://npm.io/package/babel-plugin-react-native-web.md) ~0.21.0
- [@babel/plugin-transform-for-of](https://npm.io/package/@babel/plugin-transform-for-of.md) ^7.24.7
- [@babel/plugin-transform-classes](https://npm.io/package/@babel/plugin-transform-classes.md) ^7.25.4
- [@babel/plugin-transform-runtime](https://npm.io/package/@babel/plugin-transform-runtime.md) ^7.24.7
- [@babel/plugin-proposal-decorators](https://npm.io/package/@babel/plugin-proposal-decorators.md) ^7.12.9
- [@babel/plugin-transform-react-jsx](https://npm.io/package/@babel/plugin-transform-react-jsx.md) ^7.28.6
- [babel-plugin-syntax-hermes-parser](https://npm.io/package/babel-plugin-syntax-hermes-parser.md) ^0.36.0
- [babel-plugin-transform-flow-enums](https://npm.io/package/babel-plugin-transform-flow-enums.md) ^0.0.2
- [@babel/plugin-transform-parameters](https://npm.io/package/@babel/plugin-transform-parameters.md) ^7.24.7
- [@babel/plugin-transform-typescript](https://npm.io/package/@babel/plugin-transform-typescript.md) ^7.25.2
- [@react-native/babel-plugin-codegen](https://npm.io/package/@react-native/babel-plugin-codegen.md) 0.86.3
- [@babel/plugin-syntax-dynamic-import](https://npm.io/package/@babel/plugin-syntax-dynamic-import.md) ^7.8.3
- [@babel/plugin-transform-block-scoping](https://npm.io/package/@babel/plugin-transform-block-scoping.md) ^7.25.0
- [@babel/plugin-transform-destructuring](https://npm.io/package/@babel/plugin-transform-destructuring.md) ^7.24.8
- [@babel/plugin-transform-unicode-regex](https://npm.io/package/@babel/plugin-transform-unicode-regex.md) ^7.24.7
- [@babel/plugin-syntax-optional-chaining](https://npm.io/package/@babel/plugin-syntax-optional-chaining.md) ^7.8.3
- [@babel/plugin-transform-private-methods](https://npm.io/package/@babel/plugin-transform-private-methods.md) ^7.24.7
- [@babel/plugin-syntax-export-default-from](https://npm.io/package/@babel/plugin-syntax-export-default-from.md) ^7.24.7
- [@babel/plugin-transform-class-properties](https://npm.io/package/@babel/plugin-transform-class-properties.md) ^7.25.4
- [@babel/plugin-transform-flow-strip-types](https://npm.io/package/@babel/plugin-transform-flow-strip-types.md) ^7.25.2
- [@babel/plugin-transform-modules-commonjs](https://npm.io/package/@babel/plugin-transform-modules-commonjs.md) ^7.24.8
- [@babel/plugin-transform-optional-chaining](https://npm.io/package/@babel/plugin-transform-optional-chaining.md) ^7.24.8
- [@babel/plugin-proposal-export-default-from](https://npm.io/package/@babel/plugin-proposal-export-default-from.md) ^7.24.7
- [@babel/plugin-transform-async-to-generator](https://npm.io/package/@babel/plugin-transform-async-to-generator.md) ^7.24.7
- [@babel/plugin-transform-class-static-block](https://npm.io/package/@babel/plugin-transform-class-static-block.md) ^7.27.1
- [@babel/plugin-transform-object-rest-spread](https://npm.io/package/@babel/plugin-transform-object-rest-spread.md) ^7.24.7
- [@babel/plugin-transform-react-display-name](https://npm.io/package/@babel/plugin-transform-react-display-name.md) ^7.24.7
- [@babel/plugin-transform-export-namespace-from](https://npm.io/package/@babel/plugin-transform-export-namespace-from.md) ^7.25.9
- [@babel/plugin-transform-react-jsx-development](https://npm.io/package/@babel/plugin-transform-react-jsx-development.md) ^7.27.1
- [@babel/plugin-transform-optional-catch-binding](https://npm.io/package/@babel/plugin-transform-optional-catch-binding.md) ^7.24.7
- [@babel/plugin-transform-react-pure-annotations](https://npm.io/package/@babel/plugin-transform-react-pure-annotations.md) ^7.27.1
- [@babel/plugin-syntax-nullish-coalescing-operator](https://npm.io/package/@babel/plugin-syntax-nullish-coalescing-operator.md) ^7.8.3
- [@babel/plugin-transform-async-generator-functions](https://npm.io/package/@babel/plugin-transform-async-generator-functions.md) ^7.25.4
- [@babel/plugin-transform-private-property-in-object](https://npm.io/package/@babel/plugin-transform-private-property-in-object.md) ^7.24.7
- [@babel/plugin-transform-nullish-coalescing-operator](https://npm.io/package/@babel/plugin-transform-nullish-coalescing-operator.md) ^7.24.7
- [@babel/plugin-transform-logical-assignment-operators](https://npm.io/package/@babel/plugin-transform-logical-assignment-operators.md) ^7.24.7
- [@babel/plugin-transform-named-capturing-groups-regex](https://npm.io/package/@babel/plugin-transform-named-capturing-groups-regex.md) ^7.24.7

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 57.0.12 (latest) — 2026-09-15
- 58.0.1 (next) — 2026-09-14
- 58.0.0-canary-20260909-ea7a89a (canary) — 2026-09-09
- 56.0.20 (sdk-56) — 2026-08-28
- 55.0.25 (sdk-55) — 2026-08-25
- 54.0.12 (sdk-54) — 2026-07-15
- 56.0.14-canary-20260701-9100865 (canary-sdk-56) — 2026-07-01
- 55.0.9-canary-20260429-a5e59cf (canary-sdk-55) — 2026-04-29
- 12.0.12 (sdk-52) — 2026-01-31
- 13.2.5 (sdk-53) — 2026-01-31
- 11.0.6 (sdk-51) — 2024-05-13
- 10.0.1 (sdk-50) — 2023-12-19
- 58.0.0 — 2026-09-10
- 57.0.11 — 2026-09-08
- 58.0.0-canary-20260902-26df09e — 2026-09-02
- … 324 more at https://npm.io/package/babel-preset-expo/versions

## README

# babel-preset-expo

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.

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

## Options

### `react-compiler`

Settings 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`.

```js
[
  'babel-preset-expo',
  {
    'react-compiler': {
      sources: (filename) => {
        // Match file names to include in the React Compiler.
        return filename.includes('src/path/to/dir');
      },
    },
  },
];
```

### `minifyTypeofWindow`

Set `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.

```js
[
  '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.

### `reanimated`

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

### `worklets`

`boolean`, `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`.

### [`jsxRuntime`](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#runtime)

`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](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#how-to-upgrade-to-the-new-jsx-transform) 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.

```js
[
  'babel-preset-expo',
  {
    jsxRuntime: 'classic',
  },
];
```

This property is passed down to [`@babel/plugin-transform-react-jsx`](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx).

### [`jsxImportSource`](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#importsource)

`string`, defaults to `react`

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

```js
[
  'babel-preset-expo',
  {
    jsxRuntime: 'automatic',
    jsxImportSource: 'react',
  },
];
```

This property is passed down to [`@babel/plugin-transform-react-jsx`](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx). This options does nothing when `jsxRuntime` is not set to `automatic`.

### [`lazyImports`](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy)

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:

- `null` - [@react-native/babel-preset](https://github.com/facebook/react-native/tree/main/packages/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](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy).
- `Array<string>` - [babel-plugin-transform-modules-commonjs](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy) will handle it.
- `(string) => boolean` - [babel-plugin-transform-modules-commonjs](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy) 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`

```js
[
    'babel-preset-expo',
    {
        lazyImports: true
    }
],
```

### `disableImportExportTransform`

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.

```js
// 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.

```js
[
    'babel-preset-expo',
    {
        disableImportExportTransform: true
    }
],
```

### `unstable_transformProfile`

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`](https://docs.expo.dev/versions/latest/config/app/#jsengine) option in your `app.json`.

### `transformImportMeta`

Enable transform that converts `import.meta` to `globalThis.__ExpoImportMetaRegistry`. Defaults to `true`.

> **Note:** If the JavaScript engine supports `import.meta` natively, this transformation may interfere with the native implementation.

### `enableBabelRuntime`

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:

```js
[
  'babel-preset-expo',
  {
    // Default value:
    disableImportExportTransform: false,

    web: {
      // Web-specific value:
      disableImportExportTransform: true,
    },
  },
];
```

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

### Babel Loader

The Babel loading mechanism must include the following properties on its `caller`.

#### platform

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    |

#### bundler

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][metro]     |
| `webpack` | Bundling with [Webpack][webpack] |

[metro]: https://facebook.github.io/metro/
[webpack]: https://webpack.js.org/

---
_Source: https://npm.io/package/babel-preset-expo · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
