CJS/ESM Error in hyrdrogen

Topic summary

A developer is encountering a CJS/ESM module error when attempting to integrate react-redux and @reduxjs/toolkit into a Hydrogen app.

Initial Approach:

  • Followed a YouTube tutorial to resolve the issue
  • Configured vite.config.ts with ssr.noExternal, cjsInterop plugin, and optimizeDeps.exclude settings
  • Error persists with a ReferenceError: module is not defined related to use-sync-external-store

Solution Provided:
Another user (Lmail) suggested a simplified configuration:

  • Move use-sync-external-store/with-selector.js to ssr.optimizeDeps.include instead of excluding it
  • Remove the cjsInterop plugin and ssr.noExternal configurations
  • Keep standard Hydrogen/Remix plugin setup

Outcome:
The original poster thanked Lmail, suggesting the simplified approach resolved the issue. The key fix appears to be properly including the external store dependency rather than excluding or attempting complex interop configurations.

Summarized with AI on November 8. AI used: claude-sonnet-4-5-20250929.

I’ve watched this video https://www.youtube.com/watch?v=jmNuEEtwkD4 to try and fix this error however this did not fix my issue

This is my vite.config.ts file:

import {defineConfig} from 'vite';
import {hydrogen} from '@shopify/hydrogen/vite';
import {oxygen} from '@shopify/mini-oxygen/vite';
import {vitePlugin as remix} from '@remix-run/dev';
import tsconfigPaths from 'vite-tsconfig-paths';
import {cjsInterop} from 'vite-plugin-cjs-interop';

export default defineConfig({
  ssr: {
    noExternal: ['react-redux', '@reduxjs/toolkit', 'use-sync-external-store'],
  },
  plugins: [
    hydrogen(),
    oxygen(),
    remix({
      presets: [hydrogen.preset()],
      future: {
        v3_fetcherPersist: true,
        v3_relativeSplatPath: true,
        v3_throwAbortReason: true,
      },
    }),
    tsconfigPaths(),
    cjsInterop({
      dependencies: [
        'react-redux',
        '@reduxjs/toolkit',
        'use-sync-external-store',
      ],
    }),
  ],
  optimizeDeps: {
    exclude: ['use-sync-external-store'],
  },
  build: {
    // Allow a strict Content-Security-Policy
    // withtout inlining assets as base64:
    assetsInlineLimit: 0,
  },
});

and this is the error I’m getting, I’m trying to add react-redux and @reduxjs/toolkit to my hydrogen app:

›   Warning: Could not find ts-node at /Users/charlielamb/Documents/divert/yom/node_modules/@shopify/cli/dist/index-e6f8190d.js. Please ensure that ts-node is a devDependency.
 ›    Falling back to compiled source.
ReferenceError: module is not defined
    at /Users/charlielamb/Documents/divert/yom/node_modules/use-sync-external-store/with-selector.js:6:3
    at Object.runViteModule (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1181:17)
    at ViteRuntime.directRequest (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1026:78)
    at ViteRuntime.cachedRequest (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:949:28)
    at request (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:976:128)
    at /node_modules/react-redux/dist/react-redux.mjs?v=78bdc88b:2:31
    at Object.runViteModule (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1181:11)
    at ViteRuntime.directRequest (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:1026:60)
    at ViteRuntime.cachedRequest (Users/charlielamb/Documents/divert/yom/node_modules/@shopify/mini-oxygen/dist/vite/worker-entry.js:950:79)
    at /app/lib/hooks.ts:1:110

how can I fix this error? I’ve installed ts-node as a dev dependency already.

Hi Charlietlamb - You should be able to get a simple redux example working in a hydrogen app with the following:

export default defineConfig({
  ssr: {
    optimizeDeps: {include: ['use-sync-external-store/with-selector.js']},
  },
  plugins: [
    hydrogen(),
    oxygen(),
    remix({
      presets: [hydrogen.preset()],
      future: {
        v3_fetcherPersist: true,
        v3_relativeSplatPath: true,
        v3_throwAbortReason: true,
      },
    }),
    tsconfigPaths(),
  ],
  build: {
    // Allow a strict Content-Security-Policy
    // withtout inlining assets as base64:
    assetsInlineLimit: 0,
  },
});

Hope this helps!

1 Like

Thanks Liam!