Repository navigation
Conversation
This is an initial commit for the migration towards ESM. meshoptimizer will stop supporting CJS (except for meshopt_decoder.cjs which will be added later) to simplify the build and deployment process. As a first step, remove the CJS files and rename ESM files so that js/meshopt_clusterizer.js et al is the canonical name for the module.
Now that the package is marked as "module", tests need to use import instead of require.
This file can be require'd or used in non-ESM friendly environments instead of the previously available js/meshopt_decoder.js which is now ESM only. This is exclusive for the decoder; other modules will not have a CJS-equivalent replacement.
We no longer have .module.js files and .js files are now ESM.
Instead of using UMD, use ESM for library.js. Instead of automatically initializing the module in node, move the initialization to cli.js which is node-specific. We don't need the TextEncoder workaround anymore either.
We no longer use .module extension and the .js files are now ESM.
We now support exporting individual modules by name as well.
For decoder, we still maintain the .cjs file to ensure maximum compatibility.
meshopt_decoder.js is now ESM, and .module.js doesn't exist.
zeux
force-pushed
the
js-esm
branch
2 times, most recently
from
October 8, 2025 20:30
51e205a to
eb6c76d
Compare
This improves compatibility when the package is used through node; we used to automatically init the package using synchronous file loads. To do that, we need to dynamically import node's fs module to avoid taking a bundle-time dependency on it in browser builds.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
As of this PR, meshoptimizer and gltfpack NPM modules are ESM-only. All
.module.jsfiles are renamed to just.js.Any use from Node that currently uses
import 'meshoptimizer'should still work as is with no changes. Imports of specific files may need to be adjusted to remove the.modulesuffix.Any use from Node via
requireneeds to use--experimental-require-moduleon earlier Node versions, or switch toimport.Any use from the web browser needs to use
import, with the exception of MeshoptDecoder which, for maximum compatibility, is still maintained as a non-ESM module (available viameshopt_decoder.cjsalthough it supports other legacy JS module loaders too).In addition, meshoptimizer NPM package now provides exports that support importing individual modules e.g.
import { MeshoptEncoder } from 'meshoptimizer/encoder'.Why do this?
Maintaining two separate files for each component is becoming onerous. In node.js environment, currently most dependents (glTF-Transform, Cesium, etc.) are using ESM anyhow, but it gets routed to CJS module by Node's behavior - and fixing that is impossible without changing the file names or directory structure due to how Node determines the type of each file.
Why do this now?
This is a breaking change that's bound to happen at some point as the ecosystem migrates to ESM. meshoptimizer 1.0, the first major version, is around the corner. It's likely that meshoptimizer 2.0 won't ship for 5+ more years, and I don't want to wait for 5 more years to drop pre-ESM support.
On the flip side, node 18 and earlier are out of support, and node 20+ should even support the require-ESM feature which makes migration for existing node projects easy even if they don't use ESM.
Thanks to Don McCurdy for discussions and advice