You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> Warning Non-javascript file is specified in 'scripts'.
Pkg will probably fail to parse. Specify *.js in glob.
/Users/manuelastudillo/Dev/myapp/node_modules/axios/dist/node/axios.cjs.map
> Warning Babel parse has failed: Missing semicolon. (1:10)
then it continues with the same errors as before:
Warning Failed to make bytecode node18-x64 for file /snapshot/myapp/node_modules/axios/dist/node/axios.cjs.map
> Warning Failed to make bytecode node18-x64 for file /snapshot/myapp/node_modules/axios/index.js
> Warning Failed to make bytecode node18-x64 for file /snapshot/myapp/node_modules/axios/lib/axios.js
I suggest to try pre-building your application using es-build and then pkg against the single file bundle. Otherwise if you are able to spot the error feel free to submit a PR
Let's use this issue for all the others. Seems that starting from nodejs 18.19.0 and for all nodejs 20+ versions some modules that support both esm and cjs are not bundled correctly. This is IMO due to resolve package that is not able to correctly parse package.json exports fields (see issue).
Let's use this issue as a tracker for such issues instead of having multiple open ones.
The error will look like:
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\snapshot\my-yao-pkg\node_modules\@apollo\server\dist\cjs\index.js from C:\snapshot\my-yao-pkg\main.cjs not supported.
index.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead either rename index.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in C:\snapshot\my-yao-pkg\node_modules\@apollo\server\package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).
at Module.require (pkg/prelude/bootstrap.js:1851:31)
at Object.<anonymous> (C:\snapshot\my-yao-pkg\main.cjs)
at Module._compile (pkg/prelude/bootstrap.js:1930:22) {
code: 'ERR_REQUIRE_ESM'
}
Alternative solutions
Below some solutions I tried and other possible working ones
[recommended] Use node --experimental-require-module option
In most cases adding --options experimental-require-module to pkg command line will solve the issue. This will not work if the imported module uses top level awaits
Note that this solution doesn't only solve this issue but also produces very small binaries. That example also handles .node native addons, them require a little monkey patch on the file that is described in the link above. Feel free to add some more context to this.
Using bpkg
Other possible solution is to use bpkg tool instead of esbuild. I still never tried it so if someone does please give me some feedbacks. It should handle node native addons out of the box better then esbuild as it encodes them in base64 into the bundle.
I belive a lot in this feature and I think it will be the future of packaging nodejs applications. Anyway it's still experimental, if you would like to give it a try please add your feedback here.
Reacted by T. Todua, Keith Speers, Daniel Caspers, Adam K Dean, Yadhukrishna S Pai, Eric Gonzalez, FlorentMasson and Towfiq I.
Reacted by Corentin Mors, Keith Speers and Gian Lazzarini
That's really exciting news, but I've already given up on using pkg with ESM because I wanted to support the import syntax in the VM and use the latest packages. It looks like I can go back to pkg now?
Let's use this issue for all the others. Seems that starting from nodejs 18.19.0 and for all nodejs 20+ versions some modules that support both esm and cjs are not bundled correctly. This is IMO due to resolve package that is not able to correctly parse package.json exports fields (see issue).
Let's use this issue as a tracker for such issues instead of having multiple open ones.
The error will look like:
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\snapshot\my-yao-pkg\node_modules\@apollo\server\dist\cjs\index.js from C:\snapshot\my-yao-pkg\main.cjs not supported.
index.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead either rename index.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in C:\snapshot\my-yao-pkg\node_modules\@apollo\server\package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).
at Module.require (pkg/prelude/bootstrap.js:1851:31)
at Object.<anonymous> (C:\snapshot\my-yao-pkg\main.cjs)
at Module._compile (pkg/prelude/bootstrap.js:1930:22) {
code: 'ERR_REQUIRE_ESM'
}
Alternative solutions
Below some solutions I tried and other possible working ones
Note that this solution doesn't only solve this issue but also produces very small binaries. That example also handles .node native addons, them require a little monkey patch on the file that is described in the link above. Feel free to add some more context to this.
Using bpkg
Other possible solution is to use bpkg tool instead of esbuild. I still never tried it so if someone does please give me some feedbacks. It should handle node native addons out of the box better then esbuild as it encodes them in base64 into the bundle.
I belive a lot in this feature and I think it will be the future of packaging nodejs applications. Anyway it's still experimental, if you would like to give it a try please add your feedback here.
My issue
I've been trying for a while to resolve this issue, as I'm stuck behind without the option to add some modules that shipped with the esm format (many packages push versions with this format only).
I've tried to use ESBuild, but seems to have just the same problem 🥲
My esbuild.ts
import{PluginBuild,build}from'esbuild'import{cwd}from'node:process'import{esbuildDecorators}from'@anatine/esbuild-decorators'constexternal=[// ...Object.keys(devDependencies || {}),'@nestjs/microservices','@nestjs/platform-express','@nestjs/websockets/socket-module','@nestjs/microservices/microservices-module','@nestjs/microservices','class-transformer','class-validator',]// from https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487constnativeNodeModulesPlugin={name: 'native-node-modules',setup(build: PluginBuild){// If a ".node" file is imported within a module in the "file" namespace, resolve// it to an absolute path and put it into the "node-file" virtual namespace.build.onResolve({filter: /\.node$/,namespace: 'file'},(args)=>({path: require.resolve(args.path,{paths: [args.resolveDir]}),namespace: 'node-file',}))// Files in the "node-file" virtual namespace call "require()" on the// path from esbuild of the ".node" file in the output directory.build.onLoad({filter: /.*/,namespace: 'node-file'},(args)=>({contents: ` import path from ${JSON.stringify(args.path)} try { module.exports = require(path) } catch {} `,}))// If a ".node" file is imported within a module in the "node-file" namespace, put// it in the "file" namespace where esbuild's default loading behavior will handle// it. It is already an absolute path since we resolved it to one above.build.onResolve({filter: /\.node$/,namespace: 'node-file'},(args)=>({path: args.path,namespace: 'file',}))// Tell esbuild's default loading behavior to use the "file" loader for// these ".node" files.letopts=build.initialOptionsopts.loader=opts.loader||{}opts.loader['.node']='file'},}asyncfunctionmyBuilder(tsconfig: string,entryPoints: string[]){constcommonjsPlugin: any=awaitimport('@chialab/esbuild-plugin-commonjs')constCWD=cwd()constbuildResult=awaitbuild({platform: 'node',target: 'node20',format: 'cjs',bundle: true,sourcemap: 'external',plugins: [esbuildDecorators({
tsconfig,cwd: CWD,}),commonjsPlugin.default(),nativeNodeModulesPlugin,],
tsconfig,
entryPoints,outdir: 'dist',
external,resolveExtensions: ['.ts','.js'],treeShaking: true,allowOverwrite: true,})};(async()=>{awaitmyBuilder('tsconfig.json',['src/main.ts'])})()
Let's use this issue for all the others. Seems that starting from nodejs 18.19.0 and for all nodejs 20+ versions some modules that support both esm and cjs are not bundled correctly. This is IMO due to resolve package that is not able to correctly parse package.json exports fields (see issue).
Let's use this issue as a tracker for such issues instead of having multiple open ones.
The error will look like:
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\snapshot\my-yao-pkg\node_modules\@apollo\server\dist\cjs\index.js from C:\snapshot\my-yao-pkg\main.cjs not supported.
index.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead either rename index.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in C:\snapshot\my-yao-pkg\node_modules\@apollo\server\package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).
at Module.require (pkg/prelude/bootstrap.js:1851:31)
at Object.<anonymous> (C:\snapshot\my-yao-pkg\main.cjs)
at Module._compile (pkg/prelude/bootstrap.js:1930:22) {
code: 'ERR_REQUIRE_ESM'
}
Alternative solutions
Below some solutions I tried and other possible working ones
Note that this solution doesn't only solve this issue but also produces very small binaries. That example also handles .node native addons, them require a little monkey patch on the file that is described in the link above. Feel free to add some more context to this.
Using bpkg
Other possible solution is to use bpkg tool instead of esbuild. I still never tried it so if someone does please give me some feedbacks. It should handle node native addons out of the box better then esbuild as it encodes them in base64 into the bundle.
I belive a lot in this feature and I think it will be the future of packaging nodejs applications. Anyway it's still experimental, if you would like to give it a try please add your feedback here.
While still not an ideal solution, I had similar issues upgrading from Node 18 to Node 20 and was able to get basic support for a pkg built executable with native node modules, embedded C++ binaries, and other JS dist assets bundled and functioning with minimal effort using #10 (comment)
I still agree that for existing known mitigations, refactoring to use ESBuild may prove to be a better long term tactic.
Just wanted to let you all know that we have a successful usage of esbuild with PKG and node 20 in https://github.com/MatrixAI/Polykey-CLI - it even has native binaries involved and nix involved (all in flake.nix).
@clicktodev you are speaking about sea, the user above was not using sea (the --sea falg is missing). This issue is not related to sea at all but default pkg method. Of course sea doesn't have such issues but it doesn't provide any kind of source code protection, the code is simply injected as plain text in the nodejs binary while with pkg the code is injected as bytecode. Not only this, sea require some customization in the code to handle assets and also it requires you to bundle everything on a single file that could be tricky with big applications. AFAIK also sea doesn't support node native addons for now
one more update, it seems full support for ESM bytecode with top level await was merged recently so the next Bun release should include full support for single file executable.
Hi everyone. I have just submitted a PR that introduces esm support. I checked many paths but I ended up adding a way to detect esm files and convert them to CJS using esbuild. This is still not working 100% as it doesn't support top level await and import.meta but works in most cases. Feedbacks are welcome 🙏🏼
Thanks for your work however top level await support is critical for my project because a critical dependency uses top level await so it's out of my control which means i'll keep using Bun for now.
pkg/prelude/bootstrap.js:1925
return wrapper.apply(this.exports, args);
^
TypeError: undefined is not a function
at /snapshot/my-ink-cli/dist/cli.js
at /snapshot/my-ink-cli/dist/cli.js
at /snapshot/my-ink-cli/dist/cli.js
at Object.<anonymous> (/snapshot/my-ink-cli/dist/cli.js)
at Module._compile (pkg/prelude/bootstrap.js:1925:22)
at Object..js (node:internal/modules/cjs/loader:1896:10)
at Module.load (node:internal/modules/cjs/loader:1484:32)
at Module._load (node:internal/modules/cjs/loader:1303:12)
at Module.runMain (pkg/prelude/bootstrap.js:1978:12)
at node:internal/main/run_main_module:33:47
Node.js v24.13.0
Activity
robertsLando commentedon Jan 8, 2024
What's the error you see on console when you run the app? I have axios too in my project and using that solution works for me
manast commentedon Jan 18, 2024
In my case I get these errors to begin with:
then it continues with the same errors as before:
and so on...
robertsLando commentedon Jan 19, 2024
I suggest to try pre-building your application using es-build and then pkg against the single file bundle. Otherwise if you are able to spot the error feel free to submit a PR
[-]Axios build error[/-][+]ESM Modules not supported[/+]robertsLando commentedon Feb 15, 2024
Let's use this issue for all the others. Seems that starting from nodejs 18.19.0 and for all nodejs 20+ versions some modules that support both esm and cjs are not bundled correctly. This is IMO due to resolve package that is not able to correctly parse package.json
exportsfields (see issue).Let's use this issue as a tracker for such issues instead of having multiple open ones.
The error will look like:
Alternative solutions
Below some solutions I tried and other possible working ones
[recommended] Use node
--experimental-require-moduleoptionIn most cases adding
--options experimental-require-moduletopkgcommand line will solve the issue. This will not work if the imported module uses top level awaitsUsing
esbuildActually a possible solution is to use esbuild to pre-compile the bundle in cjs and then use pkg on the output bundle file. I have a working example of this in this repo: https://github.com/zwave-js/zwave-js-ui/blob/master/esbuild.js
Note that this solution doesn't only solve this issue but also produces very small binaries. That example also handles
.nodenative addons, them require a little monkey patch on the file that is described in the link above. Feel free to add some more context to this.Using
bpkgOther possible solution is to use bpkg tool instead of
esbuild. I still never tried it so if someone does please give me some feedbacks. It should handle node native addons out of the box better then esbuild as it encodes them in base64 into the bundle.Use Nodejs Single executable
Docs: https://nodejs.org/api/single-executable-applications.html.
I belive a lot in this feature and I think it will be the future of packaging nodejs applications. Anyway it's still experimental, if you would like to give it a try please add your feedback here.
manast commentedon Feb 15, 2024
The only approach that finally worked for me was to use esbuild, but it was still a huge undertaking, as my project is quite large an complex...
robertsLando commentedon Feb 16, 2024
@manast tried
bpkg? It should work too and should be easier. If I make it work like I want I could consider adding it to pkg behind an optionrobertsLando commentedon Mar 22, 2024
This may fix all those issues: nodejs/node#51977 (comment)
Ref: https://joyeecheung.github.io/blog/2024/03/18/require-esm-in-node-js/
luckyyyyy commentedon Mar 22, 2024
That's really exciting news, but I've already given up on using pkg with ESM because I wanted to support the import syntax in the VM and use the latest packages. It looks like I can go back to pkg now?
robertsLando commentedon Mar 23, 2024
@luckyyyyy not yet there is still not an available nodejs lts version with that and I need to play with it a bit
Avivbens commentedon May 4, 2024
My issue
I've been trying for a while to resolve this issue, as I'm stuck behind without the option to add some modules that shipped with the
esmformat (many packages push versions with this format only).I've tried to use
ESBuild, but seems to have just the same problem 🥲My
esbuild.tsErrors
DanielCaspers commentedon May 6, 2024
While still not an ideal solution, I had similar issues upgrading from Node 18 to Node 20 and was able to get basic support for a pkg built executable with native node modules, embedded C++ binaries, and other JS dist assets bundled and functioning with minimal effort using #10 (comment)
I still agree that for existing known mitigations, refactoring to use ESBuild may prove to be a better long term tactic.
CMCDragonkai commentedon May 10, 2024
Just wanted to let you all know that we have a successful usage of esbuild with PKG and node 20 in https://github.com/MatrixAI/Polykey-CLI - it even has native binaries involved and nix involved (all in flake.nix).
29 remaining items
feat(yargs): update yargs to 18.0.0
feat(yargs): update yargs to 18.0.0
feat(yargs): update yargs to 18.0.0
clicktodev commentedon Feb 2, 2026
Bun's single file executables support ESM and top level await
robertsLando commentedon Feb 2, 2026
@clicktodev you are speaking about sea, the user above was not using sea (the
--seafalg is missing). This issue is not related to sea at all but default pkg method. Of course sea doesn't have such issues but it doesn't provide any kind of source code protection, the code is simply injected as plain text in the nodejs binary while with pkg the code is injected as bytecode. Not only this, sea require some customization in the code to handle assets and also it requires you to bundle everything on a single file that could be tricky with big applications. AFAIK also sea doesn't support node native addons for nowclicktodev commentedon Feb 2, 2026
Bun also supports bytecode compilation
clicktodev commentedon Feb 2, 2026
one more update, it seems full support for ESM bytecode with top level await was merged recently so the next Bun release should include full support for single file executable.
robertsLando commentedon Feb 2, 2026
@clicktodev thanks for the update 🙏🏼
robertsLando commentedon Feb 10, 2026
Hi everyone. I have just submitted a PR that introduces esm support. I checked many paths but I ended up adding a way to detect esm files and convert them to CJS using esbuild. This is still not working 100% as it doesn't support top level await and import.meta but works in most cases. Feedbacks are welcome 🙏🏼
clicktodev commentedon Feb 11, 2026
Thanks for your work however top level await support is critical for my project because a critical dependency uses top level await so it's out of my control which means i'll keep using Bun for now.
robertsLando commentedon Feb 11, 2026
I think I could use
--banner:js='(async () => {' --footer:js='})()'in esbuild when a top level await or for loop is detected.@clicktodev Could I ask you what limitations/issues (if any) you found using bun? How big is your project?
I started doing some researches in this issue: #204
robertsLando commentedon Feb 11, 2026
I have added support for top level await and import.meta. Here a detailed list of the remaining limitations: https://github.com/yao-pkg/pkg#ecmascript-modules-esm-support
@clicktodev could you try using 6.13.1 and give me some feedback?
clicktodev commentedon Feb 12, 2026
the binary crashes when i try to run it
built with
pkg dist/cli.js -t node24-macos-arm64here's a simple ink cli project that you can use to test https://github.com/clicktodev/my-ink-cli