> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Babel integration for custom transforms

> Add Babel to an Extension.js project only when you need transforms SWC cannot cover. Keep SWC as the default and scope Babel to specific files.

Add Babel only when you need transforms or plugins that SWC (Speedy Web Compiler) does not cover. Keep SWC as the default pipeline, then scope Babel to the files that need it.

## When Babel is a good fit

* You depend on Babel-only plugins or presets.
* You are migrating an existing Babel-heavy project incrementally.
* You want targeted transforms for specific file types (for example, MDX).

## Babel capabilities

| Capability                                | What it gives you                                                                              |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Targeted transforms                       | Run Babel for specific file types (for example, MDX) without replacing the full build pipeline |
| Plugin ecosystem access                   | Use Babel-only presets/plugins from existing web projects                                      |
| Incremental migration                     | Move legacy Babel extension projects to Extension.js in smaller steps                          |
| Rspack (Extension.js bundler) integration | Configure Babel through `extension.config.*` `config` hook                                     |

## Example setup

Install Babel dependencies:

<PackageManagerTabs command="install -D @babel/core @babel/preset-env babel-loader" />

Create `babel.config.json`:

```json theme={null}
{
  "presets": ["@babel/preset-env"]
}
```

Wire Babel into `extension.config.js` for MDX only:

```js theme={null}
export default {
  config: (config) => {
    config.module.rules.push({
      test: /\.mdx$/,
      use: ["babel-loader", "@mdx-js/loader"],
    });
    return config;
  },
};
```

## Replace SWC for JS/TS only if required

Use this pattern only when you need Babel to process JS/TS entry files directly:

```js theme={null}
export default {
  config: (config) => {
    config.module.rules = [
      {
        test: /\.[jt]sx?$/,
        exclude: /node_modules/,
        use: [{ loader: "babel-loader" }],
      },
      ...config.module.rules.filter(
        (rule) => !String(rule?.test || "").includes("[jt]sx"),
      ),
    ];
    return config;
  },
};
```

## Best practices

* Prefer targeted Babel usage before replacing the default JS/TS pipeline.
* Keep Babel rules explicit so loader ordering stays predictable.
* Reuse Babel only where migration or plugin compatibility requires it.

## Next steps

* Learn how to customize [Rspack configuration](/docs/features/rspack-configuration).
* Keep code quality high with [ESLint](/docs/integrations/eslint).
