---
title: 2.0 migration
sidebar_label: '2.0'
---

## Shifted Node.js/npm versions and dropped v10 support

Since Node.js v12 has reached [end of life](https://nodejs.org/en/about/releases/), Packemon now
requires at minimum v14.15 and above to run. Furthermore, we're entirely dropping v10 support, and
shifting v12 into `legacy`, v14 into `stable`, v16 into `current`, and the new v18 into
`experimental`. As part of this process, we are also bumping minimum requirements and coupled npm
versions.

The updated [`support`](../config.md#support) compatibility table is as follows.

#### Before

|      | Legacy    | Stable     | Current    | Experimental |
| ---- | --------- | ---------- | ---------- | ------------ |
| Node | >= 10.3.0 | >= 12.17.0 | >= 14.16.0 | >= 16.0.0    |
| npm  | >= 6.1.0  | >= 6.3.0   | >= 6.14.0  | >= 7.0.0     |

#### After

|      | Legacy     | Stable     | Current    | Experimental |
| ---- | ---------- | ---------- | ---------- | ------------ |
| Node | >= 12.22.0 | >= 14.15.0 | >= 16.12.0 | >= 18.0.0    |
| npm  | >= 6.14.0  | >= 6.14.0  | >= 8.1.0   | >= 8.5.0     |

Notable changes:

- v14.15 is the start of LTS
- v14.19 supports
  [Corepack](https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md#corepack)
- v16.12 supports new
  [ESM loader hooks](https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V16.md#experimental-esm-loader-hooks-api)
- v18 supports native fetch and
  [OpenSSL 3.0](https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V17.md#openssl-30)

## Shifted browser targets and dropped IE and iOS < 12 support

With Node.js versions changing (above), it was due time to audit the browser targets as well, and as
such, we have dropped Internet Explorer support entirely. This only affected `legacy` support.

We also dropped iOS 8-11 support, as these versions are more than 5 years old. The minimum supported
version is now iOS 12, which was released in 2018.

The updated [`support`](../config.md#support) compatibility table is as follows.

#### Before

|         | Legacy   | Stable              | Current        | Experimental           |
| ------- | -------- | ------------------- | -------------- | ---------------------- |
| Browser | >= IE 11 | defaults, not IE 11 | > 1%, not dead | last 2 chrome versions |
| Native  | >= iOS 8 | >= iOS 10           | >= iOS 12      | >= iOS 14              |

#### After

|         | Legacy              | Stable              | Current         | Experimental           |
| ------- | ------------------- | ------------------- | --------------- | ---------------------- |
| Browser | >= 0.10%, not IE 11 | defaults, not IE 11 | >= 1%, not dead | last 2 chrome versions |
| Native  | >= iOS 12           | >= iOS 13           | >= iOS 14       | >= iOS 15              |

A major notable change is that all targets are now on ES2015, which means you should see `const`
usage, arrow functions, and more (we no longer downlevel). If this causes issues, you should ask
yourself why you still need 7 year old syntax.

## Removed multiple `format` support when configuring a package

Previously it was possible to pass a list of formats to the [`format`](../config.md#formats)
setting, and Packemon will build them all (according to the platform). For example, a Node.js
library could have built `cjs` and `mjs` versions. However, in an effort to reduce the
[dual package hazard problem](https://nodejs.org/api/packages.html#dual-commonjses-module-packages),
Packemon now only supports a single format.

```json
// Before
{
  "format": ["cjs", "mjs"]
}
```

```json
// After
{
  "format": "mjs"
}
```

With that being said, you can work around this restriction by passing an
[array of configuration](../config) objects to the `packemon` setting. We _do not_ guarantee this
will work correctly.

> When choosing the `esm` format, Packemon will automatically build a `lib` format. This is an
> exception for backwards compatibility until the Node.js ecosystem is fully on modules.

## Removed `api` support from `--declaration`

We removed support for the `api` option, which uses
[@microsoft/api-extractor](https://api-extractor.com/) to generate a single `.d.ts` file. This
feature was rarely used, overcomplicated the implementation, and had weird edge cases that we
couldn't solve on our end.

Because of this change, the `--declaration` option on the command line is now a flag with no value.

```shell
# Before
--declaration standard
--declaration api

# After
--declaration
```

## Removed the `--analyze` option

Since Packemon now supports [customizing the Rollup config][packemon-config], the
[rollup-plugin-visualizer](https://github.com/btd/rollup-plugin-visualizer) plugin can now be
implemented in user-land, and doesn't need to exist in core.

```js
const path = require('path');
const visualizer = require('rollup-plugin-visualizer');

module.exports = {
  rollupInput(config) {
    config.plugins.push(
      visualizer((outputOptions) => ({
        filename: path.join(outputOptions.dir, 'stats.html'),
        gzipSize: true,
        open: true,
        sourcemap: true,
        template: 'treemap',
      })),
    );
  },
};
```

## Removed `.babelrc` support within each package

Packemon historically supported `.babelrc` files within packages as a means to allow custom Babel
plugins and presets per package. However, this wasn't really documented, and since we now support
[Packemon config files][packemon-config], we suggest using that instead.

```json title="packages/foo/.babelrc"
// Before
{
  "plugins": ["babel-plugin-formatjs"]
}
```

```js title="packages/foo/.packemon.js"
// After
module.exports = {
  babelOutput(config) {
    config.plugins.push('babel-plugin-formatjs');
  },
};
```

## Output of formats `esm` and `mjs` are now considered a module

While this change isn't technically breaking, and more of an accuracy fix towards the specification,
all files generated through the `esm` and `mjs` formats are now considered modules (using
[`generatedCode.symbols`](https://rollupjs.org/guide/en/#outputgeneratedcode)). This is in addition
to the `__esModule` property that is already being defined.

What this means, is that any imported value within a module context that is stringified will now
return "Module". This can mainly be used for feature detection.

[packemon-config]: ../advanced#customizing-babel-swc-and-rollup
