• Home
  • blog
  • Using ES Modules in the Browser Today

Using ES Modules in the Browser Today

This article will show you how you can use ES modules in the browser today.

Until recently, JavaScript had no concept of modules. It wasn’t possible to directly reference or include one JavaScript file in another. And as applications grew in size and complexity, this made writing JavaScript for the browser tricky.

One common solution is to load arbitrary scripts in a web page using <script> tags. However, this brings its own problems. For example, each script initiates a render-blocking HTTP request, which can make JS-heavy pages feel sluggish and slow. Dependency management also becomes complicated, as load order matters.

ES6 (ES2015) went some way to addressing this situation by introducing a single, native module standard. (You can read more about ES6 modules here.) However, as browser support for ES6 modules was initially poor, people started using module loaders to bundle dependencies into a single ES5 cross-browser compatible file. This process introduces its own issues and degree of complexity.

But good news is at hand. Browser support is getting ever better, so let’s look at how you can use ES6 modules in today’s browsers.

The Current ES Modules Landscape

Safari, Chrome, Firefox and Edge all support the ES6 Modules import syntax (Firefox behind a flag), here’s what they look like.

<script type="module">
  import { tag } from './html.js'

  const h1 = tag('h1', '👋 Hello Modules!')
// html.js
export function tag (tag, text) {
  const el = document.createElement(tag)
  el.textContent = text

  return el

Or as an external script:

<script type="module" src="app.js"></script>
// app.js
import { tag } from './html.js'

const h1 = tag('h1', '👋 Hello Modules!')

Simply add type="module" to your script tags and the browser will load them as ES Modules. The browser will follow all import paths, downloading and executing each module only once.

ES modules: Network graph showing loading

Older browsers won’t execute scripts with an unknown “type”, but you can define fallback scripts with the nomodule attribute:

<script type="module" src="module.js"></script>
<script nomodule src="fallback.js"></script>

Continue reading %Using ES Modules in the Browser Today%