From 746ddd12eef834831d3ead9fb66b50d002be8779 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 13 May 2026 12:43:27 -0400 Subject: [PATCH 1/2] feat: document sea applications setup --- .../common/install/esm-without-import.mdx | 53 ++++++++++++++++++- .../javascript/common/install/esm.mdx | 4 ++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/install/esm-without-import.mdx b/docs/platforms/javascript/common/install/esm-without-import.mdx index f7357b5f93e2a..277ae9cefad9c 100644 --- a/docs/platforms/javascript/common/install/esm-without-import.mdx +++ b/docs/platforms/javascript/common/install/esm-without-import.mdx @@ -25,7 +25,12 @@ This installation method has the fundamental restriction that only native Node.j As a result, the Sentry SDK will not capture data from database calls, queues, ORMs, third-party libraries, or other framework-specific data. -We recommend using this only if the `--import` flag is not an option for you. +We recommend using these setups only if the `--import` flag is not an option for you. + +This restriction applies when your application statically imports +`instrument.mjs` from the same ESM module graph. If you use a Node.js Single +Executable Application (SEA), use the SEA +bootstrap setup instead. @@ -55,3 +60,49 @@ import http from "http"; // Your application code goes here ``` + +## Node.js Single Executable Applications + +Node.js Single Executable Applications (SEA) may not load your Sentry instrumentation early enough, so you need to package a small bootstrap file as the SEA main instead of packaging your app entrypoint directly. + +The bootstrap imports Sentry first, then imports your real app entrypoint: + +```javascript {filename: sea-main.cjs} +(async () => { + await import("./instrument.mjs"); + await import("./app.mjs"); +})(); +``` + +Keep your Sentry setup in `instrument.mjs`: + +```javascript {tabTitle:ESM} {filename: instrument.mjs} +import * as Sentry from "@sentry/node"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, +}); +``` + +Then configure SEA to use the bootstrap as its main script and disable code +cache: + +```json {filename: sea-config.json} +{ + "main": "sea-main.cjs", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "useSnapshot": false, + "useCodeCache": false +} +``` + +This setup lets the Sentry SDK register ESM instrumentation hooks before your +application imports instrumented modules, such as Express or database clients. +Your instrumentation file and app entrypoint can stay ESM. The verified +bootstrap pattern shown here uses CommonJS only for the small SEA main. + +Node.js SEA support is still evolving, including how embedded ESM entrypoints +are configured. The important requirement is startup order: load Sentry before +loading the application modules you want Sentry to instrument. diff --git a/docs/platforms/javascript/common/install/esm.mdx b/docs/platforms/javascript/common/install/esm.mdx index d2d80d8145077..d222a843810b8 100644 --- a/docs/platforms/javascript/common/install/esm.mdx +++ b/docs/platforms/javascript/common/install/esm.mdx @@ -47,6 +47,10 @@ If it is not possible for you to pass the `--import` flag to the Node.js binary, NODE_OPTIONS="--import ./instrument.mjs" npm run start ``` +If you're building a Node.js Single Executable Application (SEA) and can't rely +on `--import` or `NODE_OPTIONS`, use the SEA +bootstrap setup instead. + We do not support ESM in Node versions before 18.19.0. ## Troubleshooting instrumentation From 81b104f6895e31f04f436ec45bcc390cedb5b2f2 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 13 May 2026 13:56:59 -0400 Subject: [PATCH 2/2] fix: added bootstrap compat for node 26 --- .../common/install/esm-without-import.mdx | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/platforms/javascript/common/install/esm-without-import.mdx b/docs/platforms/javascript/common/install/esm-without-import.mdx index 277ae9cefad9c..079f686ed629a 100644 --- a/docs/platforms/javascript/common/install/esm-without-import.mdx +++ b/docs/platforms/javascript/common/install/esm-without-import.mdx @@ -65,13 +65,25 @@ import http from "http"; Node.js Single Executable Applications (SEA) may not load your Sentry instrumentation early enough, so you need to package a small bootstrap file as the SEA main instead of packaging your app entrypoint directly. -The bootstrap imports Sentry first, then imports your real app entrypoint: +The embedded SEA main should only load a filesystem bootstrap file next to the +executable: ```javascript {filename: sea-main.cjs} -(async () => { +const { createRequire } = require("node:module"); + +createRequire(__filename)("./sea-bootstrap.cjs"); +``` + +The filesystem bootstrap imports Sentry first, then imports your real app +entrypoint: + +```javascript {filename: sea-bootstrap.cjs} +async function startApp() { await import("./instrument.mjs"); await import("./app.mjs"); -})(); +} + +startApp(); ``` Keep your Sentry setup in `instrument.mjs`: @@ -85,7 +97,7 @@ Sentry.init({ }); ``` -Then configure SEA to use the bootstrap as its main script and disable code +Then configure SEA to use `sea-main.cjs` as its main script and disable code cache: ```json {filename: sea-config.json} @@ -98,11 +110,18 @@ cache: } ``` +Keep `sea-bootstrap.cjs`, `instrument.mjs`, and `app.mjs` available on the +filesystem next to the executable. If you want a fully self-contained +executable, bundle your instrumentation and app into the SEA main instead. + This setup lets the Sentry SDK register ESM instrumentation hooks before your application imports instrumented modules, such as Express or database clients. Your instrumentation file and app entrypoint can stay ESM. The verified -bootstrap pattern shown here uses CommonJS only for the small SEA main. +bootstrap pattern shown here uses CommonJS only for the small SEA entry files. Node.js SEA support is still evolving, including how embedded ESM entrypoints -are configured. The important requirement is startup order: load Sentry before -loading the application modules you want Sentry to instrument. +and module loading are configured. The embedded SEA main may not be able to +load filesystem modules with `import()` directly, so the example above uses +`module.createRequire()` to bridge from the embedded main to a normal +filesystem bootstrap. The important requirement is startup order: load Sentry +before loading the application modules you want Sentry to instrument.