11cb0ef41Sopenharmony_ci# Maintaining Single Executable Applications support
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciSupport for [single executable applications][] is one of the key technical
41cb0ef41Sopenharmony_cipriorities identified for the success of Node.js.
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci## High level strategy
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciFrom the [Next-10 discussions][] there are 2 approaches the project believes are
91cb0ef41Sopenharmony_ciimportant to support:
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci### Compile with Node.js into executable
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciThis is the approach followed by [boxednode][].
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciNo additional code within the Node.js project is needed to support the
161cb0ef41Sopenharmony_cioption of compiling a bundled application along with Node.js into a single
171cb0ef41Sopenharmony_ciexecutable application.
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci### Bundle into existing Node.js executable
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciThis is the approach followed by [pkg][].
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciThe project does not plan to provide the complete solution but instead the key
241cb0ef41Sopenharmony_cielements which are required in the Node.js executable in order to enable
251cb0ef41Sopenharmony_cibundling with the pre-built Node.js binaries. This includes:
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci* Looking for a segment within the executable that holds bundled code.
281cb0ef41Sopenharmony_ci* Running the bundled code when such a segment is found.
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciIt is left up to external tools/solutions to:
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci* Bundle code into a single script.
331cb0ef41Sopenharmony_ci* Generate a command line with appropriate options.
341cb0ef41Sopenharmony_ci* Add a segment to an existing Node.js executable which contains
351cb0ef41Sopenharmony_ci  the command line and appropriate headers.
361cb0ef41Sopenharmony_ci* Re-generate or removing signatures on the resulting executable
371cb0ef41Sopenharmony_ci* Provide a virtual file system, and hooking it in if needed to
381cb0ef41Sopenharmony_ci  support native modules or reading file contents.
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciHowever, the project also maintains a separate tool, [postject][], for injecting
411cb0ef41Sopenharmony_ciarbitrary read-only resources into the binary such as those needed for bundling
421cb0ef41Sopenharmony_cithe application into the runtime.
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci## Planning
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciPlanning for this feature takes place in the [single-executable repository][].
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci## Upcoming features
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ciCurrently, only running a single embedded CommonJS file is supported but support
511cb0ef41Sopenharmony_cifor the following features are in the list of work we'd like to get to:
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci* Running an embedded ESM file.
541cb0ef41Sopenharmony_ci* Running an archive of multiple files.
551cb0ef41Sopenharmony_ci* Embedding [Node.js CLI options][] into the binary.
561cb0ef41Sopenharmony_ci* [XCOFF][] executable format.
571cb0ef41Sopenharmony_ci* Run tests on Alpine Linux.
581cb0ef41Sopenharmony_ci* Run tests on s390x Linux.
591cb0ef41Sopenharmony_ci* Run tests on ppc64 Linux.
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci## Disabling single executable application support
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ciTo disable single executable application support, build Node.js with the
641cb0ef41Sopenharmony_ci`--disable-single-executable-application` configuration option.
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci## Implementation
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ciWhen built with single executable application support, the Node.js process uses
691cb0ef41Sopenharmony_ci[`postject-api.h`][] to check if the `NODE_JS_CODE` section exists in the
701cb0ef41Sopenharmony_cibinary. If it is found, it passes the buffer to
711cb0ef41Sopenharmony_ci[`single_executable_application.js`][], which executes the contents of the
721cb0ef41Sopenharmony_ciembedded script.
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci[Next-10 discussions]: https://github.com/nodejs/next-10/blob/main/meetings/summit-nov-2021.md#single-executable-applications
751cb0ef41Sopenharmony_ci[Node.js CLI options]: https://nodejs.org/api/cli.html
761cb0ef41Sopenharmony_ci[XCOFF]: https://www.ibm.com/docs/en/aix/7.2?topic=formats-xcoff-object-file-format
771cb0ef41Sopenharmony_ci[`postject-api.h`]: https://github.com/nodejs/node/blob/71951a0e86da9253d7c422fa2520ee9143e557fa/test/fixtures/postject-copy/node_modules/postject/dist/postject-api.h
781cb0ef41Sopenharmony_ci[`single_executable_application.js`]: https://github.com/nodejs/node/blob/main/lib/internal/main/single_executable_application.js
791cb0ef41Sopenharmony_ci[boxednode]: https://github.com/mongodb-js/boxednode
801cb0ef41Sopenharmony_ci[pkg]: https://github.com/vercel/pkg
811cb0ef41Sopenharmony_ci[postject]: https://github.com/nodejs/postject
821cb0ef41Sopenharmony_ci[single executable applications]: https://github.com/nodejs/node/blob/main/doc/contributing/technical-priorities.md#single-executable-applications
831cb0ef41Sopenharmony_ci[single-executable repository]: https://github.com/nodejs/single-executable
84