Configure Babel

    All Babel API options are allowed. However, if the option requires JavaScript, you may want to use a JavaScript .

    • You are using a monorepo?
    • You want to compile node_modules?
    • You have a configuration that only applies to a single part of your project?
    • Guy Fieri is your hero?

    Create a file called babel.config.json with the following content at the root of your project (where the package.json is).

    1. module.exports = function (api) {
    2. api.cache(true);
    3. const presets = [ ... ];
    4. const plugins = [ ... ];
    5. return {
    6. presets,
    7. plugins
    8. };
    9. }

    Check out the babel.config.json documentation to see more configuration options.

    Create a file called .babelrc.json with the following content in your project.

    1. {
    2. "presets": [...],
    3. "plugins": [...]
    4. }

    Check out the to see more configuration options.

    Alternatively, you can choose to specify your .babelrc.json config from within package.json using the babel key like so:

    1. {
    2. "name": "my-package",
    3. "version": "1.0.0",
    4. "babel": {
    5. "presets": [ ... ],
    6. "plugins": [ ... ],
    7. }
    8. }
    1. const presets = [ ... ];
    2. const plugins = [ ... ];
    3. module.exports = { presets, plugins };

    You are allowed to access any Node.js APIs, for example a dynamic configuration based on the process environment:

    1. const presets = [ ... ];
    2. const plugins = [ ... ];
    3. if (process.env["ENV"] === "prod") {
    4. plugins.push(...);
    5. }
    6. module.exports = { presets, plugins };

    You can read more about JavaScript configuration files in the

    Check out the babel-cli documentation to see more configuration options.

    1. require("@babel/core").transformSync("code", {
    2. plugins: ["@babel/plugin-transform-arrow-functions"],
    3. });

    Check out the to see more configuration options.

    You can tell Babel to print effective configs on a given input path

    1. # *nix or WSL
    2. BABEL_SHOW_CONFIG_FOR=./src/myComponent.jsx npm start
    1. $env:BABEL_SHOW_CONFIG_FOR = ".\src\myComponent.jsx"; npm start

    BABEL_SHOW_CONFIG_FOR accepts both absolute and relative file paths. If it is a relative path, it will be resolved from cwd.

    Once Babel processes the input file specified by BABEL_SHOW_CONFIG_FOR, Babel will print effective configs to the console. Here is an example output:

    1. Babel configs on "/path/to/cwd/src/index.js" (ascending priority):
    2. config /path/to/cwd/babel.config.json
    3. {
    4. "sourceType": "script",
    5. "plugins": [
    6. "@foo/babel-plugin-1"
    7. ],
    8. "extends": "./my-extended.js"
    9. }
    10. config /path/to/cwd/babel.config.json .env["test"]
    11. {
    12. "plugins": [
    13. [
    14. "@foo/babel-plugin-3",
    15. {
    16. "noDocumentAll": true
    17. },
    18. ]
    19. ]
    20. }
    21. config /path/to/cwd/babel.config.json .overrides[0]
    22. {
    23. "test": "src/index.js",
    24. }
    25. config /path/to/cwd/.babelrc
    26. {}
    27. programmatic options from @babel/cli
    28. {
    29. "sourceFileName": "./src/index.js",
    30. "presets": [
    31. "@babel/preset-env"
    32. ],
    33. "configFile": "./my-config.js",
    34. "caller": {
    35. },
    36. "filename": "./src/index.js"
    37. }

    Babel will print effective config sources ordered by ascending priority. Using the example above, the priority is:

    1. babel.config.json < .babelrc < programmatic options from @babel/cli

    In other words, babel.config.json is overwritten by .babelrc, and .babelrc is overwritten by programmatic options.

    If your input is ignored by ignore or only, Babel will print that this file is ignored.

    Babel’s configuration merging is relatively straightforward. Options will overwrite existing options when they are present and their value is not undefined. There are, however, a few special cases:

    • For assumptions, parserOpts and generatorOpts, objects are merged, rather than replaced.
    • For plugins and presets, they are replaced based on the identity of the plugin/preset object/function itself combined with the name of the entry.

    Option (except plugin/preset) merging

    As an example, consider a config with:

    When NODE_ENV is test, the sourceType option will be replaced and the assumptions option will be merged. The effective config is:

    1. {
    2. sourceType: "module", // sourceType: "script" is overwritten
    3. assumptions: {
    4. setClassFields: true,
    5. iterableIsArray: true, // assumptions are merged by Object.assign
    6. },
    7. }

    Plugin/Preset merging

    As an example, consider a config with:

    1. plugins: [
    2. './other',
    3. ['./plug', { thing: true, field1: true }]
    4. ],
    5. overrides: [{
    6. plugins: [
    7. ['./plug', { thing: false, field2: true }],
    8. ]
    9. }]

    The overrides item will be merged on top of the top-level options. Importantly, the plugins array as a whole doesn’t just replace the top-level one. The merging logic will see that "./plug" is the same plugin in both cases, and { thing: false, field2: true } will replace the original options, resulting in a config as

    1. plugins: [
    2. './other',
    3. ['./plug', { thing: false, field2: true }],
    4. ],

    Since merging is based on identity + name, it is considered an error to use the same plugin with the same name twice in the same plugins/presets array. For example

      is considered an error, because it’s identical to . Additionally, even

      1. plugins: [["./plug", { one: true }], ["./plug", { two: true }]];

      is considered an error, because the second one would just always replace the first one.

      because each instance has been given a unique name and thus a unique identity.