#2497·systemjs

Coexistence with native import maps

Author: oravecz-jpmcCreated Oct 30, 2024Updated Apr 5, 2025
  • SystemJS Version: 6.15.1
  • Which library are you using?
    • system.js
    • s.js
    • system-node.cjs
  • Which extras are you using?
    • AMD extra
    • Named Exports
    • Named Register
    • Transform
    • Use Default
    • Global
    • Dynamic Import Maps
  • Are you using any custom hooks?

Preferred way to coexist with native import maps

I have a host application built using React in the standard manner of bundling React along with the application. This happens to be bundled using Webpack, but I expect the behavior is the same with other bundlers.

In this application, there are some components exposed as native ESM packages, and others that are exposed as both native ESM and as System.register(). They are all loaded dynamically at runtime based on URL's provided by a service call (i.e. unknown at build time).

I've been having a difficult time trying to get these components to share an instance of React which is required for host-level communication and context sharing. I did stumble across mention of this in a @guybedford post, but with a caveat that this should not be done?

index.html

xml
    <script type="importmap">
        {
            "imports": {
                "react": "/inbrowser/esm/react.production.min.js",
                "react-dom": "/inbrowser/esm/react-dom.production.min.js",
                "react/jsx-runtime": "/inbrowser/esm/react-jsx-runtime.production.min.js",
                ...other_shared_libraries
            }
        }
    </script>
    <script type="systemjs-importmap">
        {
            "imports": {
                "react": "app:react",
                "react-dom": "app:react-dom",
                "react/jsx-runtime": "app:react/jsx-runtime",
                ...other_shared_libraries
            }
        }
    </script>

index.tsx

typescript
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as JsxRuntime from 'react/jsx-runtime';

import 'systemjs';
System.set('app:react', React);
System.set('app:react-dom', ReactDOM);
System.set('app:react/jsx-runtime', JsxRuntime);

This works for me, but I'm not sure what edge cases exist. I am not worried about backwards compatibility with browsers pre-2023 that do not support native import maps, but I do want some of the enhanced features such as external import map fetching and dynamic import map features.

I'm also unclear as to how SystemJS is sometimes referred to as a polyfill. In my attempts, all shared dependencies and the remote component I am loading have to be bundled using the System.register() format which requires an invasive step into all of these libraries.

When I attempt to System.import('/path/to/esm'), I receive the Cannot use import statement outside a module exception.

Would I be better served to use the es-module-shims package for my particular use case?