One Flag to Trace Them All — `-r securenow/register` Now Works for ESM and CJS

Stop juggling --require and --import flags. securenow/register now auto-registers the ESM loader hook via module.register() on Node >=20.6, so a single -r flag is all you need for both CommonJS and ESM apps.

Lhoussine
Apr 2, 2026·5 min read

One Flag to Trace Them All — -r securenow/register Now Works for ESM and CJS

Adding OpenTelemetry to a Node.js application has historically meant remembering different flags depending on whether your project uses CommonJS or ES modules:

# CommonJS — one flag
node --require securenow/register app.js

# ESM ("type": "module") — two flags
node --import @opentelemetry/instrumentation/hook.mjs --require securenow/register app.js

Getting the second form wrong (forgetting the --import, wrong path, Windows file:// issues) meant traces silently never appeared. That two-flag requirement has been the most common support question we see.

Starting now, you only need one flag regardless of your module system:

node -r securenow/register app.js

This post explains what changed, why it works, and what you need to do (hint: almost nothing).

...

What changed: auto-ESM registration via module.register()

Node.js 20.6 introduced module.register(), a programmatic API that lets a CommonJS preload script register ESM loader hooks at runtime — the same hooks that --import registers at launch time.

securenow/register now uses this API automatically. When it loads:

  1. It checks if your app is ESM ("type": "module" in the nearest package.json).
  2. If yes and no --import hook is already present, it calls module.register() to register the OpenTelemetry ESM loader hook.
  3. Then it proceeds with the normal OTel SDK setup.

The result: a single --require securenow/register is all Node needs to instrument both CJS and ESM code.

...

How to use it

Existing start script

If you already use --require securenow/register, you are done. Nothing changes for CJS apps, and ESM apps that previously needed the extra --import flag no longer do (on Node >=20.6).

New setup

npm install securenow

Add one flag to however you start your app:

node -r securenow/register src/index.js

Or keep your existing npm start unchanged and use NODE_OPTIONS:

NODE_OPTIONS="-r securenow/register" npm start

package.json

{
  "scripts": {
    "start": "node -r securenow/register src/index.js",
    "dev": "node -r securenow/register --watch src/index.js"
  }
}

PM2

// ecosystem.config.cjs
module.exports = {
  apps: [{
    name: 'my-app',
    script: './src/index.js',
    node_args: '-r securenow/register',
    env: {
      SECURENOW_APPID: 'your-app-key',
      SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
    }
  }]
};

Docker

CMD ["node", "-r", "securenow/register", "src/index.js"]
...

Node version compatibility

Node versionCJS appsESM appsNotes
18.xSingle -r flagNeeds --import toomodule.register() not available
20.6+Single -r flagSingle -r flagAuto-ESM registration
22.xSingle -r flagSingle -r flagStable module.register()

If you are still on Node 18 with an ESM app, the register file will print a warning with the exact flags you need. But we recommend upgrading to Node 20+ — it is the current LTS and the single-flag experience is much nicer.

...

What happens under the hood

When node -r securenow/register loads:

  1. dotenv — Loads .env into process.env (optional, if dotenv is installed).
  2. ESM detection — Reads the nearest package.json to check "type": "module".
  3. Auto-register — If ESM and Node >=20.6, calls module.register('@opentelemetry/instrumentation/hook.mjs', ...). If --import is already present in process.execArgv, this step is skipped.
  4. OTel SDK — Initializes the OpenTelemetry SDK with trace exporters, log exporters, auto-instrumentation, and all the configuration from your environment variables.

The entire sequence runs before your application's first import or require, which is exactly when instrumentation needs to load.

...

Before vs after

ScenarioBeforeAfter
CJS appnode -r securenow/register app.jsnode -r securenow/register app.js (unchanged)
ESM appnode --import @opentelemetry/instrumentation/hook.mjs -r securenow/register app.jsnode -r securenow/register app.js
ESM + Windowsnode --import file:///C:/.../.../hook.mjs -r securenow/register app.jsnode -r securenow/register app.js
NODE_OPTIONSNODE_OPTIONS="--import .../hook.mjs -r securenow/register"NODE_OPTIONS="-r securenow/register"

The biggest win is for ESM users on Windows, where the file:// URL requirement for --import was a constant source of confusion.

...

What about securenow run?

The securenow CLI also includes a convenience securenow run <script> command that wraps node with the right flags. It is useful if you prefer not to modify your Node command at all, but most teams will find the -r flag simpler and more transparent since it keeps your start scripts standard node commands.

...

Conclusion

Observability should not require memorizing flag combinations. With securenow/register auto-registering the ESM hook on Node >=20.6, a single -r flag is all it takes — for CommonJS, for ESM, on Linux, macOS, and Windows.

Update your securenow package, verify your Node version, and enjoy shorter start scripts.

...

Related reading

  • The Nuxt 3 guide covers the dedicated securenow/nuxt module for Nuxt applications.
  • Other Getting Started posts in this blog cover Express, Fastify, NestJS, and more.
  • The SecureNow docs describe exporters, sampling, and the dashboard — everything after instrumentation.

Frequently Asked Questions

Do I need to change my start scripts?

Just add `-r securenow/register` to your existing `node` command, or set `NODE_OPTIONS="-r securenow/register"`. Your entry file and everything else stays the same.

What about Node 18?

Node 18 does not support `module.register()`. For ESM apps on Node 18 you still need `--import @opentelemetry/instrumentation/hook.mjs`. We recommend upgrading to Node 20+ where the single `-r` flag handles everything.

Does this work with TypeScript entry files?

Yes. Pair it with your usual TypeScript runner: `node -r securenow/register -r ts-node/register src/main.ts`, or compile first and run the JS output.

Can I still use PM2, Docker, or Kubernetes?

Absolutely. Use `node_args: '-r securenow/register'` in PM2, or `CMD ["node", "-r", "securenow/register", "app.js"]` in Docker. The flag works everywhere `node` runs.

What if I was using --import before?

It still works. If `--import @opentelemetry/instrumentation/hook.mjs` is present, the auto-registration step is skipped. There is no double-loading.

Recommended reading

Getting Started with SecureNow and Nuxt 3 — Add Security Monitoring in Under 2 Minutes

A hands-on walkthrough for adding security observability to a Nuxt 3 app using the securenow npm package and official Nuxt module. Covers installation, nuxt.config.ts setup, environment variables, optional tuning, deployment targets, CLI verification, and troubleshooting.

Apr 2
Add Security Monitoring to a Next.js App with SecureNow — Traces, Logs, and Body Capture on AWS

Step-by-step guide to integrating SecureNow into a self-hosted Next.js application on AWS EC2. Covers installation, instrumentation, environment configuration, verifying traces and logs, enabling request body capture, and creating alert rules.

Mar 29
deploy nextjs hacker news aws securenow
How to Secure Your Fastify App with SecureNow — Real-Time API Protection via OpenTelemetry

Step-by-step guide to adding security monitoring to your Fastify API with the securenow npm package. Covers CLI setup, instrumentation, body capture caveats, PM2, Docker, and dashboard verification.

Mar 26
getting started securenow fastify