Node.js
Building a Node.js app
daedalus supports Node.js apps end-to-end. It detects a Node.js project by the
presence of a package.json file, embeds the Node.js runtime with its shared
libraries, and automatically handles node_modules when present.
Example: hello-node
A minimal Node.js HTTP server:
examples/hello-node/
├── app.js
└── package.json
app.js:
const http = require("http");
const port = parseInt(process.env.PORT || "8080", 10);
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(`Hello from daedalus + Node.js ${process.version}\n");
});
server.listen(port, () => {
console.log(`Server listening on http://127.0.0.1:${port}`);
});
package.json:
{
"name": "hello-node",
"main": "app.js"
}
Build it:
daedalus build ./examples/hello-node -o hello-node.de
Run it:
./hello-node.de
# Server listening on http://127.0.0.1:8080
With dependencies (node_modules)
If your app has npm dependencies, they must be installed first (npm install)
so that node_modules/ exists in the project directory. daedalus automatically
detects it and sets NODE_PATH inside the extracted rootfs.
cd my-node-app
npm install express
daedalus build . -o my-app.de
The build output will confirm:
app layer: node_modules from /path/to/my-node-app/node_modules
How it works
detect.rsdetectspackage.jsonand finds thenodebinary on$PATH- The ELF analyzer resolves all shared libraries the Node.js runtime depends on (~18 .so files)
- The interpreter + .so files + /etc form the runtime layer (cached)
- App code +
node_modulesform the app layer (rebuilt on every change) - The launcher sets
LD_LIBRARY_PATHandNODE_PATH, thenexecvps node
Known limitations
- Native addons (
.nodefiles) are bundled but their transitive.sodependencies are not yet auto-detected. This works for most JS-only packages. - Node.js v18+ is tested. The runtime layer caches per exact binary version.