Using Import Maps and Lit Element Web Components
Tags: javascript, webcomponents, lithtml, litelement
Published: 2019-09-24 02:02:17

---
title: Using Import Maps and Lit Element Web Components
published: true
description: Learn how to use lit-html and lit-element Web Components without a build step using import maps.
tags: javascript, web-components, lit-html, lit-element
canonical_url: https://coryrylan.com/blog/using-import-maps-and-lit-element-web-components
---

When using JavaScript modules we often import with node package paths.
When loading JavaScript in the browser, the browser will not know where the package folder is because it is not a relative directory path. The path points to a `node_modules` directory where our packages are installed.

```javascript
import { html } from 'lit-element';
```

When using tools like Webpack or Rollup, they update the paths and bundle this code for us. This is a problem if we want to prototype without any build tools.

Web Component APIs in the browser are relatively low-level APIs. We can use tools like lit-html and lit-element to provide high-level abstractions. When using lit-element to build Web Components, we typically need a build step. Lit-element ships as modern es2015+ JavaScript; however, it uses import paths that are not relative file paths. Luckily an upcoming browser feature called import maps are a potential solution to save us from build tooling.

## JavaScript Module Import Maps

[Import maps](https://github.com/WICG/import-maps) are a new proposed feature for JavaScript modules. Import maps allow us to tell the browser when it sees one path for a module to use another. Our example we import from `lit-element`.

```javascript
import { html } from 'lit-element';
```

With an import map we can tell the browser to swap out `lit-element`
to use a CDN URL instead.

```html
<script type="importmap">
  {
    "imports": {
      "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module"
    }
  }
</script>
```

This snippet maps our import to our new path which points to a CDN version of the lit-html package.

```javascript
import { html } from 'https://unpkg.com/lit-html@latest/lit-html.js?module';
```

This mapping is helpful since we don't want to have to use a build step to transform the paths for us. Import maps are still a newly proposed feature, so to use them, we need to use a shim JavaScript file to provide the functionality. We will use the [`es-module-shims` polyfill](https://github.com/guybedford/es-module-shims).

```html
<!doctype html>
<html>
  <head>
    <script defer src="https://unpkg.com/es-module-shims@latest/dist/es-module-shims.js"></script>
    <script type="importmap-shim">
      {
        "imports": {
          "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module",
        }
      }
    </script>
    <script type="module-shim">
      ...
    </script>
  </head>
  <body>
   ...
  </body>
</html>
```

To use the shim, we have to suffix the module types with `shim`, so the polyfill/shim has time to process and update the paths. To use lit-element, we need to update a few paths since lit-element has a few different import paths.

```html
<script type="importmap-shim">
  {
    "imports": {
      "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module",
      "lit-element": "https://unpkg.com/lit-element@latest/lit-element.js?module",
      "lit-html/lit-html.js": "https://unpkg.com/lit-html@latest/lit-html.js?module",
      "lit-html/lib/shady-render.js": "https://unpkg.com/lit-html@latest/lib/shady-render.js?module"
    }
  }
</script>
```

Now that we have the import map set up out we can start using lit-element in our JavaScript.

```html
<!doctype html>
<html>
  <head>
    <script defer src="https://unpkg.com/es-module-shims@latest/dist/es-module-shims.js"></script>
    <script type="importmap-shim">
      {
        "imports": {
          "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module",
          "lit-element": "https://unpkg.com/lit-element@latest/lit-element.js?module",
          "lit-html/lit-html.js": "https://unpkg.com/lit-html@latest/lit-html.js?module",
          "lit-html/lib/shady-render.js": "https://unpkg.com/lit-html@latest/lib/shady-render.js?module"
        }
      }
    </script>
    <script type="module-shim">
      // you can also set a external script src with type "module-shim"
      import { LitElement, html, css } from 'lit-element';

      class XComponent extends LitElement {
        static get styles() {
          return css`
            :host {
              color: red;
            }
          `;
        }

        render() {
          return html`
            Hello from lit-element!
          `;
        }
      }

      customElements.define('x-component', XComponent);
    </script>
  </head>
  <body>
    <x-component></x-component>
  </body>
</html>
```

![Lit HTML Web Components with Import Maps](https://thepracticaldev.s3.amazonaws.com/i/vymf5zo3cmb6f5e1krs9.png)

We can now import from lit-element and start writing our Web Components.
Import maps with lit-element is excellent for quick prototyping and trying out different Web Component libraries. Want to learn more about lit html check out my other blog post [Web Components Building Web Components with lit-html](https://coryrylan.com/blog/building-web-components-with-lit-html). Check out the full working demo on [Stackblitz](https://stackblitz.com/edit/js-fbamyx).