esm.sh

A fast, smart, & global CDN for modern(es2015+) web development.

README

esm.sh


A fast, smart, & global content delivery network (CDN) for modern(es2015+) web
development.

How to Use


esm.sh is a modern CDN that allows you to import
from a URL:

  1. ```js
  2. import Module from "https://esm.sh/PKG@SEMVER[/PATH]";
  3. ```

or build a module with custom input(code):

  1. ```js
  2. import { esm } from "https://esm.sh/build";

  3. const { render } = await esm`
  4.   /* @jsx h */
  5.   import { h } from "npm:preact@10.13.2";
  6.   import { renderToString } from "npm:preact-render-to-string@6.0.2";
  7.   export const render () => renderToString(<h1>Hello world!</h1>);
  8. `;
  9. console.log(render()); // "

    Hello world!

    "
  10. ```

More usage check out here.


You may want to use _bare specifier_ instead of URL with import maps:

  1. ```html
  2. <script type="importmap">
  3.   {
  4.     "imports": {
  5.       "react": "https://esm.sh/react@18.2.0"
  6.     }
  7.   }
  8. </script>
  9. <script type="module">
  10.   import React from "react" // alias to https://esm.sh/react@18.2.0
  11. </script>
  12. ```

Importing from NPM


  1. ```js
  2. import React from "https://esm.sh/react@18.2.0";
  3. ```

You may also use a semver or a
dist-tag instead of a
fixed version number, or omit the version/tag entirely to use the latest tag:

  1. ```js
  2. import React from "https://esm.sh/react";        // 18.2.0 (latest)
  3. import React from "https://esm.sh/react@^17";    // 17.0.2
  4. import React from "https://esm.sh/react@canary"; // 18.3.0-canary-e1ad4aa36-20230601
  5. ```

You can import submodules of a package:

  1. ```js
  2. import { renderToString } from "https://esm.sh/react-dom@18.2.0/server";
  3. ```

or import/fetch non-module(js) as following:

  1. ```js
  2. import "https://esm.sh/react@18.2.0/package.json" assert { type: "json" };
  3. ```

Importing from GitHub


esm.sh supports to import modules/assets from a github repo:
/gh/OWNER/REPO[@TAG]/PATH. For example:

  1. ```js
  2. import tslib from "https://esm.sh/gh/microsoft/tslib@2.6.0";
  3. ```

or load a svg image from a github repo:
https://esm.sh/gh/microsoft/fluentui-emoji/assets/Party%20popper/Color/party_popper_color.svg

Specifying Dependencies


By default, esm.sh rewrites import specifiers based on the package dependencies.
To specify the version of these dependencies, you can add the
?deps=PACKAGE@VERSION query. To specify multiple dependencies, separate them
with a comma, like this: ?deps=react@17.0.2,react-dom@17.0.2.

  1. ```js
  2. import React from "https://esm.sh/react@17.0.2";
  3. import useSWR from "https://esm.sh/swr?deps=react@17.0.2";
  4. ```

Aliasing Dependencies


  1. ```js
  2. import useSWR from "https://esm.sh/swr?alias=react:preact/compat";
  3. ```

in combination with ?deps:

  1. ```js
  2. import useSWR from "https://esm.sh/swr?alias=react:preact/compat&deps=preact@10.5.14";
  3. ```

The original idea came from

Tree Shaking


By default, esm.sh exports a module with all its exported members. However, if
you want to import only a specific set of members, you can specify them by
adding a ?exports=foo,bar query to the import statement.

  1. ```js
  2. import { __await, __rest } from "https://esm.sh/tslib"; // 7.3KB
  3. import { __await, __rest } from "https://esm.sh/tslib?exports=__await,__rest"; // 489B
  4. ```

By using this feature, you can take advantage of tree shaking with esbuild and
achieve a smaller bundle size. Note that this feature is only supported for
ESM modules and not CJS modules.

Bundling Strategy


By default, esm.sh bundles sub-modules in the dependency tree when you import a
module.

You can also bundle all dependencies of a package into a single JS file by adding
?bundle-deps query to the import URL:

  1. ```js
  2. import { Button } from "https://esm.sh/antd?bundle-deps";
  3. ```

Bundling deps can reduce the number of network requests and improve performance.
However, it may bundle shared code repeatedly. In extreme case, it may break the
side effects of the package, or change the import.meta.url pointing. To avoid
this, you can add ?no-bundle to disable the default bundling behavior:

  1. ```js
  2. import "https://esm.sh/@pyscript/core?no-bundle";
  3. ```

For package authors, you can specify the bundling strategy by adding the esm.sh
field to package.json:

  1. ```jsonc
  2. {
  3.   "name": "foo",
  4.   "esm.sh": {
  5.     "bundle": false, // disables bundling behavior
  6.   }
  7. }
  8. ```

Development Mode


  1. ```js
  2. import React from "https://esm.sh/react?dev";
  3. ```

With the ?dev option, esm.sh builds a module with process.env.NODE_ENV set
to "development" or based on the condition development in the exports
field. This is useful for libraries that have different behavior in development
and production. For example, React will use a different warning message in
development mode.

ESBuild Options


By default, esm.sh checks the User-Agent header to determine the build target.
You can also specify the target by adding ?target, available targets are:
es2015 - es2022, esnext, deno, denonext, node and
bun.

  1. ```js
  2. import React from "https://esm.sh/react?target=es2020";
  3. ```

Other supported options of esbuild:

  js
  import foo from "https://esm.sh/foo?conditions=custom1,custom2";
  
  js
  import foo from "https://esm.sh/foo?keep-names";
  
  js
  import foo from "https://esm.sh/foo?ignore-annotations";
  

Web Worker


esm.sh supports ?worker query to load the module as a web worker:

  1. ```js
  2. import workerFactory from "https://esm.sh/monaco-editor/esm/vs/editor/editor.worker?worker";

  3. const worker = workerFactory();
  4. ```

You can pass some custom code snippet to the worker when calling the factory
function:

  1. ```js
  2. const workerAddon = `
  3. self.onmessage = function (e) {
  4.   console.log(e.data)
  5. }
  6. `;
  7. const worker = workerFactory(workerAddon);
  8. ```