What’s the purpose of the HTML “nomodule” attribute for script elements if the default is text/javascript?

The purpose of the nomodule attribute is to cause newer browsers that support module scripts to ignore a particular script element:

The nomodule attribute is a boolean attribute that prevents a script from being executed in user agents that support module scripts.

The spec has a good example:

This example shows how to include a module script for modern user agents, and a classic script for older user agents:

<script type="module" src="app.js"></script>
<script nomodule src="classic-app-bundle.js"></script>

In modern user agents that support module scripts, the script element with the nomodule attribute will be ignored, and the script element with a type of "module" will be fetched and evaluated (as a module script). Conversely, older user agents will ignore the script element with a type of "module", as that is an unknown script type for them — but they will have no problem fetching and evaluating the other script element (as a classic script), since they do not implement the nomodule attribute.

So that’s how it works.

In HTML 5, the type attribute is optional and defaults to text/javascript… Has this default changed?

The default hasn’t changed—it’s still text/javascript. But the type attribute can now also have the value module, which means browsers still parse and execute it as text/javascript—but also specifically as a module script.

If not, why would nomodule be necessary?

It’s necessary in order to prevent new browsers that support module scripts from executing a script that’s intended only for old browsers that don’t support module scripts, as in the above example.

Can I just use <script src="bundle.js"></script> without nomodule?

Yes—if bundle.js doesn’t use modules. If it uses modules, you‘d want to put type=module on it (in which case old browsers will ignore it since they don’t recognize the module value for type).


nomodule attribute

The nomodule attribute is a boolean attribute which is used to indicate to a browser which does support modules that a certain script tag doesn't need to be loaded.

The purpose of the nomodule attribute is to have a backup script for older browser who don't support the <script type="module"> and thus will ignore them. Because the older browser neither support the <script type="module"> nor the nomodule attribute the following scenarios can occur:


Newer browsers, supports <script type="module"> & <script nomodule type="text/javascript">

  • The browser can load and execute the <script type="module"> script
  • The browser recognizes the nomodule attribute and doesn't load <script nomodule type="text/javascript">.

Older browsers, don't support <script type="module"> & <script nomodule type="text/javascript">

  • The browser will ignore the <script type="module"> since its implementation cannot process this. No script will be downloaded and executed.
  • The browser will ignore the nomodule attribute since and will continue to dowload and execute the <script nomodule type="text/javascript"> script.