#353·wtfjs

CLI crashes on launch with `TypeError: meow is not a function` due to ESM/CJS mismatch

Author: codeCraft-RitikCreated Sep 14, 2026Updated Sep 14, 2026

Issue : CLI crashes on launch with TypeError: meow is not a function due to ESM/CJS mismatch

Severity & Impact

  • Severity: Critical / Blocker
  • Impact: The executable CLI binary (wtfjs) crashes immediately upon execution. Any user who installs wtfjs globally via npm install -g wtfjs and runs wtfjs is greeted with a fatal crash. The package's core executable functionality is completely broken.

Affected Files

Root Cause Analysis

In package.json, several dependencies were bumped to major versions that are pure ES Modules (ESM):

  • "meow": "^10.1.4" (v10+ is ESM-only)
  • "chalk": "^5.0.1" (v5+ is ESM-only)
  • "boxen": "^7.0.0" (v7+ is ESM-only)
  • "update-notifier": "^6.0.2" (v6+ is ESM-only)

However, package.json does not specify "type": "module", and wtfjs.js still uses CommonJS:

javascript
const boxen = require("boxen");
const chalk = require("chalk");
const updateNotifier = require("update-notifier");
const pkg = require("./package.json");
const meow = require("meow");

const cli = meow(...);
  • On Node < 22 (e.g. Node 16, 18, 20): Node throws Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported.
  • On Node 22+: Node's CJS loader loads the ESM module as a namespace object ({ __esModule: true, default: [Function: meow] }). Consequently, const meow = require("meow") assigns the namespace object, and invoking meow(...) immediately throws:
    TypeError: meow is not a function

The same issue applies to updateNotifier and boxen.

Minimal Reproducible Example

bash
$ node wtfjs.js

Actual Output

C:\Users\...\wtfjs\wtfjs.js:14
const cli = meow(
            ^

TypeError: meow is not a function
    at Object.<anonymous> (C:\Users\...\wtfjs\wtfjs.js:14:13)

Expected Output

The CLI runs smoothly, parses arguments, and pipes the manual into the pager.

Proposed Fix

There are two recommended approaches:

Option A: Modernize wtfjs.js to pure ESM (Recommended)

Add "type": "module" to package.json and convert wtfjs.js to use import:

diff
--- a/package.json
+++ b/package.json
@@ -3,4 +3,5 @@
   "version": "1.22.8",
+  "type": "module",
   "description": "A list of funny and tricky JavaScript examples",
diff
--- a/wtfjs.js
+++ b/wtfjs.js
@@ -1,13 +1,15 @@
 #!/usr/bin/env node
 
-const fs = require("fs");
-const obj = require("through2").obj;
-const pager = require("default-pager");
-const msee = require("msee");
-const join = require("path").join;
-const boxen = require("boxen");
-const chalk = require("chalk");
-const updateNotifier = require("update-notifier");
-const pkg = require("./package.json");
-const meow = require("meow");
+import fs from "node:fs";
+import { createRequire } from "node:module";
+import { fileURLToPath } from "node:url";
+import { dirname, join } from "node:path";
+import boxen from "boxen";
+import chalk from "chalk";
+import pager from "default-pager";
+import meow from "meow";
+import msee from "msee";
+import updateNotifier from "update-notifier";
+
+const require = createRequire(import.meta.url);
+const pkg = require("./package.json");
+const __dirname = dirname(fileURLToPath(import.meta.url));

Option B: Revert dependencies to CommonJS versions

Pin dependencies to their latest CommonJS releases:

json
"dependencies": {
  "boxen": "^5.1.2",
  "chalk": "^4.1.2",
  "default-pager": "^1.1.0",
  "meow": "^9.0.0",
  "msee": "^0.3.3",
  "through2": "^4.0.2",
  "update-notifier": "^5.1.0"
}