Skip to main content

4.0 migration

Shifted supported platform versions

Since Node.js v16 has reached end of life, Packemon now requires at minimum v18.12 and above to run. Furthermore, we're entirely dropping v14 support, and shifting v16 into legacy, v18 into stable, v20 into current, and the new v21 into experimental. As part of this process, we are also bumping minimum requirements and coupled npm versions.

The updated support compatibility table is as follows.

Before

LegacyStableCurrentExperimental
node>= 14.15.0>= 16.12.0>= 18.12.0>= 19.0.0
npm>= 6.14.0>= 8.1.0>= 8.19.0>= 9.0.0
electron>= 7>= 11>= 16>= 21
nativeiOS 13iOS 14iOS 15iOS 16

After

LegacyStableCurrentExperimental
node>= 16.12.0>= 18.12.0>= 20.10.0>= 21.6.0
npm>= 8.1.0>= 8.19.0>= 10.0.0>= 10.4.0
electron>= 11>= 16>= 21>= 26
nativeiOS 14iOS 15iOS 16iOS 17

Notable Node.js changes:

  • Supports fetch natively.
  • Registering ESM hooks.
  • import.meta.resolve()
  • --experimental-detect-module
  • --experimental-default-type

Packemon is now ESM only

We've finished our migration to an ESM only package by shipping only .mjs files. This was made possible by our underlying @boost framework, which was also converted to ESM only in v5. For users of Packemon, ESM only should be entirely transparent to you, but at minimum, you should see increased performance and reduced memory usage, as ESM is far more performant than CJS.

React Native now supports esm target

Over the last year, Metro, the React Native bundler has received a ton of new features, such as symlinks support, ESM support, package.json exports/imports, Hermes integration, Terser, Node.js 18+, and much more.

Since Metro has been modernized to such an extent, we're now confident in it's ESM support, so have added esm as a valid format for the native platform.

Streamlined exports and the default condition

Packemon has supported automatic package.json exports since its inception, and we believe this to be one of its greatest features. However, automating exports correctly has been very difficult to get right, especially when building a package for multiple platforms and formats.

One of the biggest issues that users face, is when a package is built for browers only, only a browser export condition is generated. This looks correct, and is, but when it's not. For non-bundler environments, such as Node.js and TypeScript, this condition is completely ignored, resulting in "missing exports or types" errors. Although the package is built correctly, this feels like a bug, and is a poor developer experience. It's also very confusing on how to fix it, especially when a user has no knowledge on how exports and conditions work.

To remedy this problem, we've implemented a new algorithm that will automatically flatten exports and add a default condition if it does not exist. The default condition is supported by all tools, and should avoid the problem above. We believe this will work much better, but we're also not 100% confident it will work correctly for all use cases, so all feedback is appreciated!