# @expo/webpack-config

> A Webpack configuration used to bundle Expo websites with Expo CLI.

Latest version **19.0.1** (published 2024-01-17) · MIT license · 0 weekly downloads

## Install

```sh
npm install @expo/webpack-config
pnpm add @expo/webpack-config
yarn add @expo/webpack-config
bun add @expo/webpack-config
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 19.0.1 |
| Published | 2024-01-17 |
| First published | 2019-03-08 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >=12 |
| Dependencies | 23 |
| Unpacked size | 432.1 KB |
| Known vulnerabilities | 0 (+6 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 13 |
| Author | Expo |
| Maintainers | radoslawkrzemien, pkham, szdziedzic, tsapeta, wkozyra, ide, lukmccall, kadikraman, aleqsio, marklawlor, gabrieldonadel, simek, keith-kurak, christopherwalter, kbrandwijk, fiber-god, brentvatne, evanbacon, quinlanj, expoadmin, exponent, wschurman, bycedric, jonsamp, princefleaswallow, kudochien |

## Links

- npm: https://www.npmjs.com/package/@expo/webpack-config
- Repository: https://github.com/expo/expo-webpack-integrations
- Homepage: https://github.com/expo/expo-webpack-integrations/tree/main/packages/webpack-config#readme
- Issues: https://github.com/expo/expo-webpack-integrations/issues
- npm.io page: https://npm.io/package/@expo/webpack-config

## Dependencies (23)

- [chalk](https://npm.io/package/chalk.md) ^4.0.0
- [getenv](https://npm.io/package/getenv.md) ^1.0.0
- [is-wsl](https://npm.io/package/is-wsl.md) ^2.0.0
- [semver](https://npm.io/package/semver.md) ~7.5.4
- [find-up](https://npm.io/package/find-up.md) ^5.0.0
- [webpack](https://npm.io/package/webpack.md) ^5.64.4
- [expo-pwa](https://npm.io/package/expo-pwa.md) 0.0.127
- [fs-extra](https://npm.io/package/fs-extra.md) ^11.2.0
- [css-loader](https://npm.io/package/css-loader.md) ^6.5.1
- [@babel/core](https://npm.io/package/@babel/core.md) ^7.20.2
- [babel-loader](https://npm.io/package/babel-loader.md) ^8.3.0
- [style-loader](https://npm.io/package/style-loader.md) ^3.3.1
- [node-html-parser](https://npm.io/package/node-html-parser.md) ^5.2.0
- [source-map-loader](https://npm.io/package/source-map-loader.md) ^3.0.1
- [webpack-dev-server](https://npm.io/package/webpack-dev-server.md) ^4.11.1
- [copy-webpack-plugin](https://npm.io/package/copy-webpack-plugin.md) ^10.2.0
- [html-webpack-plugin](https://npm.io/package/html-webpack-plugin.md) ^5.5.0
- [clean-webpack-plugin](https://npm.io/package/clean-webpack-plugin.md) ^4.0.0
- [terser-webpack-plugin](https://npm.io/package/terser-webpack-plugin.md) ^5.3.0
- [mini-css-extract-plugin](https://npm.io/package/mini-css-extract-plugin.md) ^2.5.2
- [webpack-manifest-plugin](https://npm.io/package/webpack-manifest-plugin.md) ^4.1.1
- [find-yarn-workspace-root](https://npm.io/package/find-yarn-workspace-root.md) ~2.0.0
- [css-minimizer-webpack-plugin](https://npm.io/package/css-minimizer-webpack-plugin.md) ^3.4.1

## Recent versions

- 19.0.1 (latest) — 2024-01-17
- 0.12.61-alpha.0 (alpha) — 2021-03-03
- 0.4.1-alpha.0 (next) — 2019-03-28
- 0.1.0-alpha.0 (canary) — 2019-03-08
- 18.1.4 — 2024-01-05
- 18.1.3 — 2023-09-11
- 19.0.0 — 2023-08-25
- 18.1.2 — 2023-07-21
- 18.1.1 — 2023-07-05
- 18.1.0 — 2023-05-30
- 18.0.4 — 2023-04-12
- 18.0.3 — 2023-04-03
- 18.0.2 — 2023-03-28
- 18.0.1 — 2023-01-27
- 18.0.0 — 2023-01-27
- … 213 more at https://npm.io/package/@expo/webpack-config/versions

## README

<!-- Title -->
<h1 align="center">
👋 Welcome to <br/><code>@expo/webpack-config</code>
</h1>

<!-- Header -->

<p align="center">
    <b>Webpack config that's optimized for running universal React and react-native-web projects</b>
    <br/>
    <br/>
    <a aria-label="Circle CI" href="https://circleci.com/gh/expo/expo-cli/tree/main">
        <img alt="Circle CI" src="https://flat.badgen.net/circleci/github/expo/expo-cli?label=Circle%20CI&labelColor=555555&icon=circleci">
    </a>
</p>

---

> ⚠️ Expo Webpack is in maintenance mode. We are actively working on a universal bundling solution that works for all platforms.

## [Documentation][docs]

To learn more about how to use this Webpack config, check out the docs here: [Customizing the Webpack config][docs]

### Contributing to the docs

- [Documentation for the master branch][docs-latest]
- [Documentation for the latest stable release][docs]

## API

Running `expo customize:web` will generate this default config in your project.

```js
const createExpoWebpackConfigAsync = require('@expo/webpack-config');

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  // Customize the config before returning it.
  return config;
};
```

## Types

### `Environment`

The main options used to configure how `@expo/webpack-config` works.

| name          | type                                    | default     | description                                         |
| ------------- | --------------------------------------- | ----------- | --------------------------------------------------- |
| `projectRoot` | `string`                                | required    | Root of the Expo project.                           |
| `https`       | `boolean`                               | `false`     | Should the dev server use https protocol.           |
| `mode`        | `Mode`                                  | required    | The Webpack mode to bundle the project in.          |
| `platform`    | [`ExpoPlatform`](#ExpoPlatform)         | required    | The target platform to bundle for.                  |
| `pwa`         | `boolean`                               | `true`      | Generate the PWA image assets in production mode.   |
| `babel`       | [`ExpoBabelOptions`](#ExpoBabelOptions) | `undefined` | Control how the default Babel loader is configured. |

### `Environment` internal

| name        | type         | default     | description                                                        |
| ----------- | ------------ | ----------- | ------------------------------------------------------------------ |
| `config`    | `ExpoConfig` | `undefined` | The Expo project config, this should be read using `@expo/config`. |
| `locations` | `FilePaths`  | `undefined` | Paths used to locate where things are.                             |

### `ExpoPlatform`

| type   | description |
| ------ | ----------- | ----- | ----------- | ---------------------------------------------------------------------------------------------------------- |
| `'ios' | 'android'   | 'web' | 'electron'` | The target platform to bundle for. Native platforms are experimental and require a special native runtime. |

### `ExpoBabelOptions`

Control how the default Babel loader is configured.

| name                                   | type       | default     | description                                                               |
| -------------------------------------- | ---------- | ----------- | ------------------------------------------------------------------------- |
| `dangerouslyAddModulePathsToTranspile` | `string[]` | `undefined` | Add the names of node_modules that should be included transpilation step. |

## Guides

### PWAs

- See the docs for [`expo-pwa`](../pwa) to learn more about creating the assets manually.
- Disable automatic PWA generation with `expo build:web --no-pwa`.
- `expo build:web` will automatically skip any PWA asset that's already linked in the project's local `web/index.html`.
- Having sharp CLI installed globally will speed up asset generation, if it's not installed, Jimp will be used instead.

#### Chrome PWAs

##### Manifest.json

The `manifest.json` will be created using the values in the project's `app.config.js`:

Generating the `manifest.json` will be skipped if the following exists in the project's `web/index.html`:

<details><summary>Show HTML</summary>

```html
<link rel="manifest" href="..." />
```

</details>

If the `icons` array is defined in your `manifest.json`, then Chrome PWA icon generation will be skipped.

##### Chrome PWA Icons

Icons will be generated using the file defined in your `app.config.js` under `android.icon` and it'll fallback to `icon`.

<details><summary>Show manifest.json</summary>

```json
{
  "icons": [
    {
      "src": "...",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "...",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "...",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
```

</details>

#### Favicons

Favicons will be generated using the file defined in your `app.config.js` under `web.favicon` and it'll fallback to `icon`.

Asset generation for Favicons will be individually skipped if any of the following fields exist in your `web/index.html`:

<details><summary>Show HTML</summary>

```html
<link rel="icon" type="image/png" sizes="16x16" href="..." />
<link rel="icon" type="image/png" sizes="32x32" href="..." />
<link rel="shortcut icon" href="..." />
```

</details>

#### Safari PWAs

Icons will be generated using the file defined in your `app.config.js` under `ios.icon` and it'll fallback to `icon`. The splash screens look at `ios.splash` and fallback to `splash`.

Asset generation for Safari PWA icons/splash screens will be individually skipped if any of the following fields exist in your `web/index.html`:

##### Icons

<details><summary>Show HTML</summary>

```html
<link rel="apple-touch-icon" sizes="180x180" href="..." />
```

</details>

##### Splash Screens

<details><summary>Show HTML</summary>

```html
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
  href="..."
/>
<link
  rel="apple-touch-startup-image"
  media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
  href="..."
/>
```

</details>

### Include modules

You may find that you want to include universal modules that aren't part of the default modules. You can do this by customizing the Webpack config:

```ts
const createExpoWebpackConfigAsync = require('@expo/webpack-config');

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(
    {
      ...env,
      babel: {
        dangerouslyAddModulePathsToTranspile: [
          // Ensure that all packages starting with @evanbacon are transpiled.
          '@evanbacon',
        ],
      },
    },
    argv
  );
  return config;
};
```

### Modify the babel loader

If you want to modify the babel loader further, you can retrieve it using the helper method `getExpoBabelLoader` like this:

```ts
const createExpoWebpackConfigAsync = require('@expo/webpack-config');
const { getExpoBabelLoader } = require('@expo/webpack-config/utils');

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  const loader = getExpoBabelLoader(config);
  if (loader) {
    // Modify the loader...
  }
  return config;
};
```

### Service workers

> Example of using service workers with Expo: `npx create-react-native-app -t with-workbox`

This webpack config currently does not supply service workers by default, they can be added to the project locally: [Adding Service Workers](https://github.com/expo/fyi/blob/main/enabling-web-service-workers.md).

## Environment Variables

- `EXPO_WEBPACK_DEFINE_ENVIRONMENT_AS_KEYS`: Should the define plugin explicitly set environment variables like `process.env.FOO` instead of creating an object like `proces.env: { FOO }`. Defaults to `false`. Next.js uses this to prevent overwriting injected environment variables.
- `IMAGE_INLINE_SIZE_LIMIT`: By default, images smaller than 10,000 bytes are encoded as a data URI in base64 and inlined in the CSS or JS build artifact. Set this to control the size limit in bytes. Setting it to 0 will disable the inlining of images. This is only used in production.

## License

The Expo source code is made available under the [MIT license](LICENSE). Some of the dependencies are licensed differently, with the BSD license, for example.

<!-- Footer -->

---

<p>
    <a aria-label="sponsored by expo" href="http://expo.dev">
        <img src="https://img.shields.io/badge/Sponsored_by-Expo-4630EB.svg?style=for-the-badge&logo=EXPO&labelColor=000&logoColor=fff" target="_blank" />
    </a>
    <a aria-label="expo webpack-config is free to use" href="/LICENSE" target="_blank">
        <img align="right" alt="License: MIT" src="https://img.shields.io/badge/License-MIT-success.svg?style=for-the-badge&color=33CC12" target="_blank" />
    </a>
</p>

[docs]: https://docs.expo.dev/guides/customizing-webpack/
[docs-latest]: https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/guides/customizing-webpack.md

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