Skip to content

🐛 [Bug]: @storyblok/[email protected] and @storyblok/[email protected]: "type": "module" causes CJS dist files to be misidentified as ESM #437

@benedictbihl

Description

@benedictbihl

Package

@storyblok/react (React Integration) & @storyblok/js

Bug Description

Both @storyblok/[email protected] and @storyblok/[email protected] set "type": "module" in their package.json, but the files referenced by the require export condition and main field are CJS/UMD -- not ESM. This causes Node.js to misidentify them as ES modules, breaking any toolchain that loads these packages via require().

Steps to Reproduce

mkdir storyblok-repro && cd storyblok-repro
npm init -y
npm install @storyblok/react@5.4.22 react react-dom
node -e "const sb = require('@storyblok/react'); console.log(Object.keys(sb));"

produces Error: Cannot find module './core/init.js'

running this to remove the "type:module" field

node -e "
const fs = require('fs');
['node_modules/@storyblok/js/package.json', 'node_modules/@storyblok/react/package.json'].forEach(p => {
  const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
  delete pkg.type;
  fs.writeFileSync(p, JSON.stringify(pkg, null, 2));
});
"
node -e "const sb = require('@storyblok/react'); console.log(Object.keys(sb));"

returns all exports correctly

Expected Behavior

Remove "type": "module" from package.json -- .js files default to CJS (matching their content), .mjs files remain ESM (extension always takes precedence).

Actual Behavior

This breaks any toolchain that loads these packages through require() rather than import(). In our case, Playwright's TypeScript transpiler converts import statements to require() calls. When a test file transitively imports @storyblok/react (e.g. test → mock → page component → storyblok utils → @storyblok/react), we get:

Error: Unexpected module status 5. Cannot require() ES Module
.../node_modules/@storyblok/react/dist/index.js because it is not yet
fully loaded. This may be caused by a race condition if the module is
simultaneously dynamically import()-ed via Promise.all().
(from packages/utils/src/storyblok/initializeStoryblok.ts)

Code Sample

Environment

System:
    OS: macOS 26.2
    CPU: (12) arm64 Apple M4 Pro
    Memory: 636.97 MB / 24.00 GB
    Shell: 4.2.1 - /opt/homebrew/bin/fish
  Binaries:
    Node: 22.16.0 - /Users/x/.local/state/fnm_multishells/6096_1771250704913/bin/node
    npm: 10.9.2 - /Users/x/.local/state/fnm_multishells/6096_1771250704913/bin/npm
    pnpm: 10.24.0 - /Users/x/.local/state/fnm_multishells/6096_1771250704913/bin/pnpm
  Browsers:
    Chrome: 144.0.7559.134
    Firefox: 146.0.1
    Safari: 26.2
  npmPackages:
    @storyblok/react: ^5.4.22 => 5.4.22
    next: 15.5.12 => 15.5.12
    react: ^19.1.2 => 19.2.4
    storyblok: ^4.14.1 => 4.14.1

Error Logs

Additional Context

we fixed this on our end with a pnpm patch removing the field, restoring expected behaviour

diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -1,4 +1,3 @@
 {
   "name": "@storyblok/react",
-  "type": "module",
   "version": "5.4.22",

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions