.Net application development specialists
asp.net, c#, vb.net, html, javascript, jquery, html, xhtml, css, oop, design patterns, sql server, mvc and much more
contact: admin@paxium.co.uk

Paxium is the company owned by myself, Dave Amour and used for providing IT contract development services including


  • Application development - Desktop, Web, Services - with Classic ASP, Asp.net WebForms, Asp.net MVC, Asp.net Core
  • Html, Css, JavaScript, jQuery, React, C#, SQL Server, Ado.net, Entity Framework, NHibernate, TDD, WebApi, GIT, IIS
  • Database schema design, implementation & ETL activities
  • Website design and hosting including email hosting
  • Training - typically one to one sessions
  • Reverse Engineering and documentation of undocumented systems
  • Code Reviews
  • Performance Tuning
  • Located in Cannock, Staffordshire
Rugeley Chess Club Buying Butler Cuckooland Katmaid Pet Sitting Services Roland Garros 60 60 Golf cement Technical Conformity Goofy MaggieBears Vacc Track Find Your Smart Phone eBate Taylors Poultry Services Lafarge Rebates System Codemasters Grid Game eBate DOFF

Pros And Cons Of Including Scripts as Modules - ie type="module">

What changes when you add type="module"?

  • Top‑level await works in modern browsers.
  • Module scope: top‑level bindings aren’t put on window.
  • Deferred by default: module scripts execute after HTML parsing (like defer).
  • Strict mode is automatic, no "use strict" needed.
  • Imports/exports become available.

Classic script

<script>
  // No top-level await
  // Globals leak onto window
  console.log(window.foo); // undefined
  var foo = 42;
  console.log(window.foo); // 42
</script>

Module script

<script type="module">
  // Works:
  const data = await fetch('/api/info').then(r => r.json());
  // No global leak:
  var foo = 42;
  console.log(window.foo); // undefined
</script>

Downsides & differences to be aware of

  • Isolation: other scripts can’t “see” your variables unless you explicitly export/import or assign to window.
  • Timing: because modules are deferred, code won’t run until HTML is parsed. If you relied on blocking execution, this changes behaviour.
  • Multiple modules ≠ shared scope: two <script type="module"> tags are separate modules.
  • Imports need correct headers: if importing from another file or origin, ensure proper Content-Type and CORS.
  • Legacy browsers: IE11 and very old browsers don’t support modules; top‑level await requires relatively recent versions.

When it’s a good idea

  • Your code is modern‑only and doesn’t need IE/very old Safari/Android browsers.
  • You don’t depend on globals leaking to window.
  • You’re happy with deferred execution after HTML parsing.
  • You want simpler async usage via top‑level await.

Useful patterns

1) Keep a “main” feel, but with top‑level await

<script type="module">
  // Top-level await for bootstrap:
  const config = await fetch('/config.json').then(r => r.json());

  // Then run your app:
  startApp(config);

  function startApp(cfg){
    const el = document.getElementById('app');
    el.textContent = `Ready: ${cfg.name}`;
  }
</script>

2) Intentionally expose a global (if you must)

<script type="module">
  // Scoped by default:
  function greet(name){ return `Hello, ${name}`; }

  // Make it global on purpose:
  window.greet = greet;
</script>

<script>
  // Classic scripts can now use it:
  console.log(greet('world'));
</script>

3) Share between modules using imports/exports

// utils.js
export const sleep = (ms) => new Promise(r => setTimeout(r, ms));

// app.js
import { sleep } from './utils.js';
await sleep(200);
console.log('awake');
<script type="module" src="/app.js"></script>

4) Feature-detect modules (very old fallback)

<script type="module">
  // modern path
  import('/app.js');
</script>
<script nomodule>
  // fallback path for very old browsers
  // (Serve a transpiled bundle here)
  <script src="/legacy-bundle.js"></script>
</script>

FAQ

Does type="module" make my script slower?

Generally no. It changes execution timing (deferred), not performance. Top‑level await pauses your module until the awaited work completes—as intended.

Can I still run code as soon as possible?

Yes—place the module near the end of <body>, or keep it in <head> and rely on the default defer-like behavior. For DOM‑dependent work, waiting for parsing is often ideal.

What about CORS and MIME types?

When importing files (especially cross‑origin), ensure they’re served with Content-Type: application/javascript and that the server allows CORS where needed.

© 2025 — Handy notes on modern JS modules & top‑level await. Feel free to drop this file into your snippets folder.