Systemjs
Dynamic ES module loader
Install / Use
/learn @systemjs/SystemjsREADME
SystemJS
SystemJS is a hookable, standards-based module loader. It provides a workflow where code written for production workflows of native ES modules in browsers (like Rollup code-splitting builds), can be transpiled to the System.register module format to work in older browsers that don't support native modules, running almost-native module speeds while supporting top-level await, dynamic import, circular references and live bindings, import.meta.url, module types, import maps, integrity and Content Security Policy with compatibility in older browsers back to IE11.
Sponsors
<a href="https://opencollective.com/systemjs/sponsor/0/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/1/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/2/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/3/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/4/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/5/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/6/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/7/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/8/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/systemjs/sponsor/9/website" target="_blank"><img src="https://opencollective.com/systemjs/sponsor/9/avatar.svg"></a>
Support SystemJS by becoming a sponsor. Your logo will show up here with a link to your website.
Backers
Thank you to all our backers! 🙏 [Become a backer]
<a href="https://opencollective.com/systemjs#backers" target="_blank"><img src="https://opencollective.com/systemjs/backers.svg?width=890"></a>
Overview
1. s.js minimal production loader
The minimal 2.8KB s.js production loader includes the following features:
- Loads
System.registermodules, the CSP-compatible SystemJS module format. - Support for loading bare specifier names with import maps via
<script type="systemjs-importmap">. - Supports hooks for loader customization.
2. system.js loader
The 4.2KB system.js loader adds the following features in addition to the s.js features above:
- Tracing hooks and registry deletion API for reloading workflows.
- Supports loading Wasm, CSS and JSON module types.
- Includes the global loading extra for loading global scripts, useful for loading library dependencies traditionally loaded with script tags.
3. system-node.cjs loader
The system-node.cjs loader is a version of SystemJS build designed to run in Node.js, typically for workflows where System modules need to be executed on the server like SSR. It has the following features:
- Loading System modules from disk (via
file://urls) or the network, with included caching that respects the Content-Type header. - Import Maps (via the
applyImportMapapi). - Tracing hooks and registry deletion API for reloading workflows.
- Loading global modules with the included global loading extra.
Loading CommonJS modules is not currently supported in this loader and likely won't be. If you find you need them it is more advisable to use Node.js native module support where possible instead of the SystemJS Node.js loader.
Extras
The following pluggable extras can be dropped in with either the s.js or system.js loader:
- AMD loading support (through
Window.definewhich is created). - Named register supports
System.register('name', ...)named bundles which can then be imported asSystem.import('name')(as well as AMD named define support) - Dynamic import maps support. This is currently a potential new standard feature.
The following extras are included in system.js loader by default, and can be added to the s.js loader for a smaller tailored footprint:
- Global loading support for loading global scripts and detecting the defined global as the default export. Useful for loading common library scripts from CDN like
System.import('//unpkg.com/lodash'). - Module Types
.css,.wasm,.jsonmodule type loading support in line with the existing modules specifications.
Since all loader features are hookable, custom extensions can be easily made following the same approach as the bundled extras. See the hooks documentation for more information.
SystemJS Babel
To support easy loading of TypeScript or ES modules in development SystemJS workflows, see the SystemJS Babel Extension.
SystemJS does not support direct integration with the native ES module browser loader because there is no way to share dependencies between the module systems. For extending the functionality of the native module loader in browsers, see ES module Shims, which like SystemJS, provides workflows for import maps and other modules features, but on top of base-level modules support in browsers, which it does using a fast Wasm-based source rewriting to remap module specifiers.
Performance
SystemJS is designed for production modules performance roughly only around a factor of 1.5 times the speed of native ES modules, as seen in the following performance benchmark, which was run by loading 426 javascript modules (all of @babel/core) on a Macbook pro with fast wifi internet connection. Each test was the average of five page loads in Chrome 80.
| Tool | Uncached | Cached | | ---- | -------- | ------ | | Native modules | 1668ms | 49ms | | SystemJS | 2334ms | 81ms |
Getting Started
The systemjs-examples repo contains a variety of examples demonstrating how to use SystemJS.
Installation
npm install systemjs
Documentation
Example Usage
Loading a System.register module
You can load System.register modules with a script element in your HTML:
<script src="system.js"></script>
<script type="systemjs-module" src="/js/main.js"></script>
<script type="systemjs-module" src="import:name-of-module"></script>
Loading with System.import
You can also dynamically load modules at any time with System.import():
System.import('/js/main.js');
where main.js is a module available in the System.register module format.
Bundling workflow
For an example of a bundling workflow, see the Rollup Code Splitting starter project - https://github.com/rollup/rollup-starter-code-splitting.
Note that when building System modules you typically want to ensure anonymous System.register statements like:
System.register([], function () { ... });
are emitted, as these can be loaded in a way that behaves the same as normal ES modules, and not named register statements like:
System.register('name', [], function () { ... });
While these can be supported with the named register extension, this approach is typically not recommended for modern modules workflows.
Import Maps
Say main.js depends on loading 'lodash', then we can define an import map:
<script src="system.js"></script>
<script type="systemjs-importmap">
{
"imports": {
"lodash": "https://unpkg.com/lodash@4.17.10/lodash.js"
}
}
</script>
<!-- Alternatively:
<script type="systemjs-importmap" src="path/to/map.json" crossorigin="anonymous"></script>
-->
<script type="systemjs-module" src="/js/main.js"></script>
IE11 Support
IE11 continues to be fully supported, provided the relevant polyfills are available.
The main required polyfill is a Promise polyfill. If using import maps a fetch polyfill is also needed.
Both of these can be loaded conditionally using for example using [Bluebird Promises](http://b
