Skip to content

ESM-only builds#3064

Draft
mfedderly wants to merge 4 commits into
masterfrom
mf/esm-only
Draft

ESM-only builds#3064
mfedderly wants to merge 4 commits into
masterfrom
mf/esm-only

Conversation

@mfedderly

@mfedderly mfedderly commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Migrate to esm-only packaging, which allows us to drop tsup.

BREAKING:

  • This breaks node@18 compatibility, as it has no way to require() an ESM module (not even with a flag).

Todo:

  • Add arethetypeswrong coverage
  • Set package.json engines to node >= 22
  • Specify 'evergreen' JS target in docs
  • Github settings: set branch protection on master to only require 22, 24, 26 passing
  • Probably needs to be re-staged as many separate smaller PRs
  • Add note on esModuleInterop / allowSyntheticDefaultImports being true in alignment with typescript@7

NodeJS previous releases
NodeJS end of life includes details on outstanding CVEs

Update 2026-05-21 - rebased after merging the consumer-style testing into master, removing it from this PR
Update 2026-05-28 - rebased to pull #3070 into its own PR

@mfedderly mfedderly added this to the v8 milestone May 11, 2026
@mfedderly mfedderly marked this pull request as draft May 11, 2026 13:04
Comment thread package.json
Comment on lines -8 to -10
"lint:escheck-cjs": "es-check es8 packages/*/dist/cjs/index.cjs packages/turf/turf.min.js",
"lint:escheck-esm": "es-check --module es8 packages/*/dist/esm/index.js",
"lint:escheck-web": "es-check es5 packages/turf/turf.min.js",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

escheck-cjs is no longer necessary because we're dropping cjs builds in this PR.

escheck-web is only necessary if you don't trust the Rollup step to output valid syntax. It has caught some things in the past where newer rollups ship catch{} syntax which isn't es5, but we're also going to move this way forward to es2022 or similar with Turf@8.

escheck-esm is no longer necessary and we are instead protected by tsconfig.shared.json's target of es2022 (in this PR). TypeScript will prevent us from using syntax that isn't supported at this version (which aligns with the tsconfig suggestions for node 22.

Comment thread tsconfig.shared.json
"module": "node16",
"outDir": "${configDir}/dist",
"target": "es2022",
"module": "node18",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to call this out another time (it was in the commit message), node18 is actually a relatively strict setting and we would expect node >= 22 and all bundlers to be supported by the output here.

Comment thread tsconfig.shared.json
"target": "es2017",
"module": "node16",
"outDir": "${configDir}/dist",
"target": "es2022",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This aligns with node@22 and should limit our syntax to things that will work in all supported versions of node. It should also work in all browsers that are reasonably in use today, but we are also going to document that we intend to ship 'evergreen' js and expect users to transpile in their bundle step if they have specific needs.

Comment thread tsconfig.shared.json
"target": "es2022",
"module": "node18",
"declaration": true,
"esModuleInterop": true,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that setting this to false makes us more strict and gives our users fewer surprises when we change things. It forces us to make sure our own code works without the interop support.

Comment thread tsconfig.shared.json
"strict": true,
"moduleResolution": "node16",
"importHelpers": true,
"skipLibCheck": true,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the above, we intentionally incur the additional strictness by enabling checking of the lib types, so that anyone running full lib checking while consuming Turf will not be surprised by issues our CI missed.

@mfedderly

Copy link
Copy Markdown
Collaborator Author

I pulled some of the test harness stuff out into its own PR

@mfedderly mfedderly force-pushed the mf/esm-only branch 4 times, most recently from fa6e109 to c80ebfd Compare May 28, 2026 13:02
mfedderly added 4 commits May 29, 2026 09:16
- Remove deprecated tsup in favor of native tsc for all TypeScript builds. When we only ship ESM we don't need an extra tool for building.
- Remove `tslib` as a dependency, and remove `importHelpers` from tsconfig. We're targeting a new enough syntax that it should not be required.
- Update tsconfig `target` from `es2017` to `es2022`, and `module` from `node16` to `node18`. These align with our new minimum supported target of node@22 and supported browsers. They're also restrictive enough that we expect them to be broadly compatible.
- Remove `esModuleInterop` (which implies `true`) from tsconfig. typescript@7 will remove this flag entirely and `true` will be the value going forward. There are a few packages with issues when this is set to `false`, but they are probably not worth chasing down if the ecosystem is headed in the other direction.
- Removes 18.x for master, but keeps it for a theoretical support/7.x branch
- Removes support/6.x which hasn't been used in a long time
- Notably this keeps node@20 for advisory reasons, it has about 3x the usage of node 18 and isn't holding back new code adoption (yet)

See NodeJS download counts by version here: https://storage.googleapis.com/access-logs-summaries-nodejs/nodejs.org-access.log.20260513.json
@mfedderly

Copy link
Copy Markdown
Collaborator Author

Note: this build is failing because it has changes from #3070 as a prerequisite, but they aren't staged in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant