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
I am working right now onto installing node.js onto OpenWRT routers. Due to memory restrictions I am afraid that it employs more space that we actually pursue, and sometimes way more than routers can actually hold.
How can we achieve the smallest node binary possible?
We want to (cross-)compile node from source to achieve the minimal disk use possible
SSL/TLS is mandatory for us, but for example npm is not.
Links will be appreciated. I have been querying google for a couple of days now, but got little information. Thank you all. Hope that this question is reusable for the community.
Sure I was considering it, but can you give some more insight on what you are pointing? There are lots of cross-compilers and methods, but I am more interested on removing dependencies and editing makefiles.
I've separated nodejs and nodejs-npm for separate cross-compilable packages for deployment to embedded devices. There is also a build time helper for calling cross-compiling capable npm install so that Node.js based software with native dependencies can be pre-compiled and packaged for deployment to minimal storage devices.
This is considered production quality so it can be used in shipping embedded products.
I know OpenWRT is not using OE compatible build system, but thought this might give you some pointers to right direction.
.. also you can separate the bundled openssl and zlib from the node.js binary and use shared libraries potentially saving you some space; especially if those libraries are used elsewhere in your embedded device software stack.
I read your question as "compiling on the device itself, how can we use the least space possible?" but I gather it's more about reducing the size of the final binary? Strip the debug info (it's enabled by default), link everything dynamically and disable i18n; ./configure --help has the details.
Linking against a shared openssl and v8 are probably the biggest wins but please note that dynamic linking is not really supported and may not work unless you're linking against the exact same version that node uses (including any patches we float.)
Just edited the question to reflect @bnoordhuis point. Yes it is more about reducing the size of the final binary.
Also it is really helpful to note:
linking is not really supported and may not work unless you're linking against the exact same version
that node uses
Since node is a priority for our design, is important to take that in account.
Thank you.
I'm using musl as libc on NodeOS and binary size got reduced a couple of megabytes (about 9.6mb for Node.js v0.11.14). Also it was suggested to move build-ins to global node_modules folder, so binary size gets smaller and use less memory since only get loaded required modules. I was going to open an issue requesting an option for it, but after I've seen this issue maybe we can disscuss it here.
Funny you asked this question, I working on the same project @jsdario started few days ago also. Working on modding Gargoyle Firmware which uses OpenWRT sources to build a custom version of the firmware. Size contraints require the size well below 4mb binary. Only need the bare minimum to run an app that uses express.js and io.js (you guys just merged so guess no longer needed separately) to create a webpage which will be the router webpage and access system information. Currently uses javascript files with sh files running through a hasbrel interpreter which I believe is totally archaic. I have lots of time today to work on this project, however, I am not sure how to start building a custom version of node. I do have a workspace to do such a task, so if someone could point me in right direction could make some custom "light" versions. I think we can both benefit from this project @jsdario :)
As @heavykcommented on NodeOS issues, I would start by moving all the build-in modules from the /lib to an external node_modules folder and force Node.js to use it, so the binary gets smaller and you can be able to remove the modules that you are not using.
Could you please report the approximate size of the reduced binary that you were able to achieve? I think that would be useful for others who are considering using node.js in an embedded system and come across this thread.
Reacted by Jakub Jirutka, Zachary Mattor, martinspaeth, Steve Cosman, James Booth, Mike Vegeto, XenoDaimon, Madan, Kobi Kai Calev, Peter Postmann and 14 more
Might you need OpenSSL for outgoing connections even if you don't need it for incoming connections? I guess it's safe to disable as long as you know you don't need it for connections in either direction.
Building against shared libraries for the dependencies may help as well. Note also that building without intl and ssl will disable many core APIs and cripple the binary in many ways. Proceed with caution.
On Arch Linux, the `nodejs` package is built with --with-intl=system-icu
and the resulting binary is 25M. So that's probably about the savings that
can be expected.
I did some comparisons of the startup times and memory use of the Arch
builds vs the official builds, which are 71M. The startup times and RSS
memory use are very close in both builds, so the primary difference really
seems to be the file size.
time node -e 'c = require("child_process"); c.exec(`ps u | grep "node
-e"`, (e, o) => console.log(o))'
Activity
bnoordhuis commentedon Sep 18, 2015
Can I suggest cross-compiling?
jsdario commentedon Sep 18, 2015
Sure I was considering it, but can you give some more insight on what you are pointing? There are lots of cross-compilers and methods, but I am more interested on removing dependencies and editing makefiles.
imyller commentedon Sep 18, 2015
I maintain OpenEmbedded build recipes for all Node.js releases at https://github.com/imyller/meta-nodejs
I've separated nodejs and nodejs-npm for separate cross-compilable packages for deployment to embedded devices. There is also a build time helper for calling cross-compiling capable
npm installso that Node.js based software with native dependencies can be pre-compiled and packaged for deployment to minimal storage devices.This is considered production quality so it can be used in shipping embedded products.
I know OpenWRT is not using OE compatible build system, but thought this might give you some pointers to right direction.
imyller commentedon Sep 18, 2015
.. also you can separate the bundled openssl and zlib from the node.js binary and use shared libraries potentially saving you some space; especially if those libraries are used elsewhere in your embedded device software stack.
jsdario commentedon Sep 18, 2015
Great @imyller that is so useful. I will share any progress into that direction.
I believe it is possible to configure SSL layer though other software (e.g a localhost proxy) and so zlib as you were pointing.
In any case if someone has faced the same question I would still like to read it.
bnoordhuis commentedon Sep 18, 2015
I read your question as "compiling on the device itself, how can we use the least space possible?" but I gather it's more about reducing the size of the final binary? Strip the debug info (it's enabled by default), link everything dynamically and disable i18n;
./configure --helphas the details.Linking against a shared openssl and v8 are probably the biggest wins but please note that dynamic linking is not really supported and may not work unless you're linking against the exact same version that node uses (including any patches we float.)
jsdario commentedon Sep 18, 2015
Just edited the question to reflect @bnoordhuis point. Yes it is more about reducing the size of the final binary.
Also it is really helpful to note:
rvagg commentedon Sep 18, 2015
and don't include ICU .. it's kind of large
[-]Build the lightest node possible[/-][+]Build the lightest node binary possible[/+]piranna commentedon Sep 21, 2015
I'm using musl as libc on NodeOS and binary size got reduced a couple of megabytes (about 9.6mb for Node.js v0.11.14). Also it was suggested to move build-ins to global node_modules folder, so binary size gets smaller and use less memory since only get loaded required modules. I was going to open an issue requesting an option for it, but after I've seen this issue maybe we can disscuss it here.
stopspazzing commentedon Sep 25, 2015
Funny you asked this question, I working on the same project @jsdario started few days ago also. Working on modding Gargoyle Firmware which uses OpenWRT sources to build a custom version of the firmware. Size contraints require the size well below 4mb binary. Only need the bare minimum to run an app that uses express.js and io.js (you guys just merged so guess no longer needed separately) to create a webpage which will be the router webpage and access system information. Currently uses javascript files with sh files running through a hasbrel interpreter which I believe is totally archaic. I have lots of time today to work on this project, however, I am not sure how to start building a custom version of node. I do have a workspace to do such a task, so if someone could point me in right direction could make some custom "light" versions. I think we can both benefit from this project @jsdario :)
piranna commentedon Sep 25, 2015
As @heavyk commented on NodeOS issues, I would start by moving all the build-in modules from the
/libto an externalnode_modulesfolder and force Node.js to use it, so the binary gets smaller and you can be able to remove the modules that you are not using.jbergstroem commentedon Sep 25, 2015
my 2c (this will not give you a full test pass build though, so beware):
stripoptionals:
-Os4 remaining items
Knighton910 commentedon Mar 9, 2016
+1 Going to close this issue, however, as there does not appear to be anything actionable here.
jsdario commentedon Mar 9, 2016
👍 Thanks all for your contributions, we made good progress from this.
drensber commentedon Oct 31, 2016
Could you please report the approximate size of the reduced binary that you were able to achieve? I think that would be useful for others who are considering using node.js in an embedded system and come across this thread.
markstos commentedon Dec 17, 2017
Might you need OpenSSL for outgoing connections even if you don't need it for incoming connections? I guess it's safe to disable as long as you know you don't need it for connections in either direction.
HardlyMirage commentedon Apr 18, 2018
Version 8.11.1
./configure && make-rwxr-xr-x 1 root root 34.7M Apr 18 19:00 out/Release/node./configure --without-intl --without-ssl && make-rwxr-xr-x 1 root root 23.4M Apr 18 19:32 out/Release/node./configure --without-intl --without-ssl && make CFLAGS='-Os'-rwxr-xr-x 1 root root 23.1M Apr 18 19:45 out/Release/nodeNote that the debugger and eslint will break with the leaner binary:
#12758 #5610
jasnell commentedon Apr 18, 2018
Building against shared libraries for the dependencies may help as well. Note also that building without intl and ssl will disable many core APIs and cripple the binary in many ways. Proceed with caution.
HardlyMirage commentedon Apr 18, 2018
I'm building upon Alpine, what shared libraries can I use here?
ORESoftware commentedon Sep 23, 2020
what's the size of the nodejs binary these days?
piranna commentedon Sep 23, 2020
71MB (73729384 bytes) for Node.js v14.11.0 on Ubuntu Linux x86_64
piranna commentedon Sep 23, 2020
So far I remember it was about 14MB in 2016, probably this size increment is due to ICU internationalization rules and data.
srl295 commentedon Sep 23, 2020
markstos commentedon Sep 23, 2020
guest271314 commentedon Apr 30, 2022
Any progress and recipe for minimal Node.js build?
Ashvith10 commentedon Jun 19, 2024
@jasnell what about the JS libraries within the
depsfolder? Wouldn't it be impossible to separate them, as they're circular dependencies?