Skip to content

/flags/javascript/node-input-type

node --input-type=module: run -e and stdin code as an ES module

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated
tool
JavaScript
command
node
flag
--input-type=<type>
default
no value: Node.js detects the syntax (commonjs when --no-experimental-detect-module is passed)
since
Node.js 12.0.0

node --input-type=module -e "..." tells Node.js to run the code passed with -e/--eval, -p/--print or on standard input as an ES module, so import, top-level await and import.meta are available and require is not. --input-type=commonjs forces CommonJS instead. The option has no effect on files: node app.js still follows the file extension and package.json "type".

The four values

bash
node --input-type=module -e 'import os from "node:os"; console.log("module:", typeof os.cpus, typeof require, typeof import.meta.url)'
node --input-type=commonjs -e 'console.log("commonjs:", typeof require, typeof module, typeof __filename)'
echo 'const n: number = 2; console.log("module-typescript:", n * 21)' | node --input-type=module-typescript
node --input-type=module -e 'require("node:path")' 2>&1 | grep Error
node --input-type=commonjs -e 'import fs from "node:fs"' 2>&1 | grep Error
node --input-type=esm -e '1' 2>&1 | sed 's/^.*node[^:]*: //'; echo "exit: ${PIPESTATUS[0]}"

Output

module: function undefined string
commonjs: function object string
module-typescript: 42
ReferenceError: require is not defined in ES module scope, you can use import instead
SyntaxError: Cannot use import statement outside a module
--input-type must be "module","commonjs", "module-typescript" or "commonjs-typescript"
exit: 9

Forcing the wrong type gives the two classic module errors: require is not defined in ES module scope in a module, and Cannot use import statement outside a module in CommonJS. An unknown value is rejected with the list of accepted ones.

ValueRuns the input asSince
moduleES module: import, export, top-level await, import.metaNode.js 12.0.0
commonjsCommonJS: require, module, __filenameNode.js 12.0.0
module-typescriptES module after stripping TypeScript typesNode.js 23.6.0, 22.18.0
commonjs-typescriptCommonJS after stripping TypeScript typesNode.js 23.6.0, 22.18.0
(not set)Detected: CommonJS first, then ES module, then with types strippedDetection on by default since 22.7.0, 20.19.0

The -typescript values are not available together with --no-strip-types.

Do you still need it?

On current Node.js, input that contains module syntax is detected automatically:

bash
node -e 'const { setTimeout: sleep } = await import("node:timers/promises"); await sleep(10); console.log("top-level await, detected as module")'
node -e 'console.log("no module syntax -> commonjs:", typeof require)'
echo 'console.log("stdin, module forced:", typeof require)' | node --input-type=module

Output

top-level await, detected as module
no module syntax -> commonjs: function
stdin, module forced: undefined

Code that has no import, export or top-level await is valid CommonJS, so detection keeps it CommonJS. Pass --input-type=module when you need ES module semantics for such code anyway (strict mode by default, no require, this is undefined at top level), in scripts that must behave the same on older Node.js versions, and to skip the detection step, which first tries to compile the input as CommonJS.

Common uses

bash
# one-liner with named imports
node --input-type=module -e 'import { readFile } from "node:fs/promises"; console.log((await readFile("package.json", "utf8")).length)'

# heredoc script in CI, run as ESM
node --input-type=module <<'EOF'
import { execSync } from "node:child_process";
console.log(execSync("git rev-parse --short HEAD").toString().trim());
EOF

For files, use .mjs or "type": "module" in package.json; the differences between the two systems are explained in require vs import.

FAQ

Does --input-type change how node app.js is loaded?

No. It applies only to code given with --eval (-e), --print (-p) or on standard input. Files are ES modules or CommonJS according to their extension (.mjs, .cjs) and the type field in the nearest package.json.

Why does node -e with import work without --input-type?

Since Node.js 22.7 and 20.19, syntax detection is on by default: Node.js first tries the input as CommonJS and, if that fails because of module syntax, runs it as an ES module. --input-type skips the guess.

How do I run TypeScript passed with -e?

Use --input-type=module-typescript or commonjs-typescript (Node.js 23.6 and 22.18 or later). Types are stripped, not checked, so type errors are not reported.

Sources