Ladybug version
@ladybugdb/core 0.20.4
What operating system are you using?
Windows x64
What happened?
When @ladybugdb/core is used from a Node.js Single Executable Application (SEA) built with pnpm pack-app, the native module file is found on disk but fails during process.dlopen() initialization:
[database] graph initializing
[database] graph failed: A dynamic link library (DLL) initialization routine failed.
<repo>\packages\command\dist-app\win32-x64\lbugjs.node
The same bundled CommonJS entry works under normal node, and the same SEA executable can initialize other native database dependencies when their native bindings are copied next to the executable:
# normal node running the bundled CJS entry
[database] relational initialized # better-sqlite3
[database] vector initialized # @lancedb/lancedb
[database] graph initialized # @ladybugdb/core
# Node SEA executable from the same CJS entry
[database] relational initialized # better-sqlite3
[database] vector initialized # @lancedb/lancedb
[database] graph failed: A dynamic link library (DLL) initialization routine failed.
...\dist-app\win32-x64\lbugjs.node
This suggests the issue is not that lbugjs.node is missing. The file is present beside the executable and @ladybugdb/core reaches the process.dlopen(lbugjs.node) path, but the DLL initialization routine fails only under the SEA executable host.
Are there known steps to reproduce?
Minimal shape of the repro:
import { Connection, Database } from '@ladybugdb/core';
const database = new Database(':memory:');
await database.init();
const connection = new Connection(database);
await connection.init();
await connection.close();
await database.close();
In the downstream project this is built as follows:
# build a CJS entry with tsdown
pnpm --filter @engineering-tender-ai/command build:sea
# normal node works
node packages/command/dist-sea/command.cjs -h
# build SEA executable
pnpm --filter @engineering-tender-ai/command pack-sea --target=win32-x64
# SEA executable fails only on LadybugDB native initialization
packages/command/dist-app/win32-x64/engineering-tender-ai.exe -h
The SEA packaging command uses Node 26.7.0:
pnpm pack-app \
--entry ./dist-sea/command.cjs \
--runtime node@26.7.0 \
--target win32-x64 \
--output-dir dist-app \
--output-name engineering-tender-ai
The downstream package copies lbugjs.node next to the executable before running it. Directory layout at runtime:
dist-app/win32-x64/
engineering-tender-ai.exe
lbugjs.node
For comparison, the same SEA executable also copies native assets for better-sqlite3 and @lancedb/lancedb; those can be initialized successfully after their native loader paths are pointed at the copied assets.
Relevant loader behavior
The published package loader uses process.dlopen() directly:
const lbugNativeModule = { exports: {} };
const modulePath = join(__dirname, 'lbugjs.node');
if (process.platform === 'linux') {
process.dlopen(
lbugNativeModule,
modulePath,
constants.RTLD_LAZY | constants.RTLD_GLOBAL
);
} else {
process.dlopen(lbugNativeModule, modulePath);
}
module.exports = lbugNativeModule.exports;
This is similar in spirit to the Electron-on-Windows native host issue discussed in #383: plain Node can load the native addon, but a non-standard Node host executable fails during native loading/initialization.
Expected behavior
@ladybugdb/core should either:
- load successfully from a Node SEA executable when
lbugjs.node is present on the real filesystem next to the executable, or
- document that Node SEA / embedded Node hosts are unsupported on Windows and explain any required build/link flags or runtime DLL dependencies.
Additional notes
I searched existing issues and did not find an exact Node SEA / single executable report. The closest prior discussion appears to be #383 for Electron on Windows, where the problem also involved native loading under a non-standard host executable.
Ladybug version
@ladybugdb/core0.20.4What operating system are you using?
Windows x64
What happened?
When
@ladybugdb/coreis used from a Node.js Single Executable Application (SEA) built withpnpm pack-app, the native module file is found on disk but fails duringprocess.dlopen()initialization:The same bundled CommonJS entry works under normal
node, and the same SEA executable can initialize other native database dependencies when their native bindings are copied next to the executable:This suggests the issue is not that
lbugjs.nodeis missing. The file is present beside the executable and@ladybugdb/corereaches theprocess.dlopen(lbugjs.node)path, but the DLL initialization routine fails only under the SEA executable host.Are there known steps to reproduce?
Minimal shape of the repro:
In the downstream project this is built as follows:
The SEA packaging command uses Node 26.7.0:
The downstream package copies
lbugjs.nodenext to the executable before running it. Directory layout at runtime:For comparison, the same SEA executable also copies native assets for
better-sqlite3and@lancedb/lancedb; those can be initialized successfully after their native loader paths are pointed at the copied assets.Relevant loader behavior
The published package loader uses
process.dlopen()directly:This is similar in spirit to the Electron-on-Windows native host issue discussed in #383: plain Node can load the native addon, but a non-standard Node host executable fails during native loading/initialization.
Expected behavior
@ladybugdb/coreshould either:lbugjs.nodeis present on the real filesystem next to the executable, orAdditional notes
I searched existing issues and did not find an exact Node SEA / single executable report. The closest prior discussion appears to be #383 for Electron on Windows, where the problem also involved native loading under a non-standard host executable.