SyntaxError: Cannot use import statement outside a module | Datadog
javascript
javascript
6월 6, 2025

SyntaxError: Cannot use import statement outside a module

Rémi Gebski
Rémi Gebski Software Engineer II

This error occurs when you’re using an import or export statement in a JavaScript file that hasn’t been explicitly declared as a module. To resolve this, you need to inform your environment—such as Node.js or a browser—that the file should be treated as an ECMAScript Module (ESM).

This is important because browsers and Node.js handle modules differently from regular scripts: they apply strict mode automatically, support top-level await, and load dependencies via import statements rather than global variables.

Node.js

In Node.js, you can enable module support in one of two ways:

  1. Set the package type to “module” in your package.json:
Copied!
1
2
3
{
  "type": "module"
}
  1. Use the .mjs file extension for your module files. Note that older version of Node.js only supported .mjs and sometimes required the --experimental-modules flag. You can read more about this in the ECMAScript modules history section.

Browsers

In browsers, simply add the attribute type="module" to your <script> tag:

Copied!
1
<script type="module" src="main.js"></script> 

All modern browsers support ESM but you may want to check the support table if you’re targeting older environments.

In most real-world browser scenarios, ESM usage also involves dynamic imports via import(), which became globally supported a bit later.

A brief history of modules

In large-scale JavaScript applications, the ability to split, scope, and reuse code is essential. Before ECMAScript Modules became a standard, JavaScript lacked a native module system. This led to the rise of various community-driven module systems, such as:

  • CommonJS
  • AMD (Asynchronous Module Definition)
  • UMD (Universal Module Definition)
  • RequireJS
  • Webpack (with its amd-like internal module loader)

Node.js and CommonJS

Node.js originally used CommonJS, which works well for synchronous module loading:

Copied!
1
2
3
// CommonJS
module.exports = {};
const foo = require('./foo.js');

However, CommonJS lacked support for asynchronous loading, which was critical for browser environments. This gap led to the creation of AMD.

AMD for the Browser

AMD was designed for browser environments where loading modules asynchronously improves the user experience:

Copied!
1
2
3
4
5
6
7
// AMD
define(['dependency'], function(dependency) {
  // Module logic here
});
require(['foo'], function(foo) {
  // Use foo
});

Popular AMD-based implementations include RequireJS, Dojo, and Webpack.

UMD: The Best of Both Worlds

With both CommonJS and AMD in use, developers needed a way to write code compatible with both systems. Enter UMD (Universal Module Definition) — a pattern that didn’t define a new module system but instead allowed libraries to be consumed in both environments.

ECMAScript Modules (ESM)

Finally, ECMAScript 2015 (ES6) introduced a standardized module system:

Copied!
1
2
3
// ESM
import foo from './foo.js';
export const bar = () => {};

Later, ES2020 introduced dynamic imports with import(), enabling asynchronous module loading natively — though browsers adopted this even before the standard.

What is Error Tracking?

Error tracking is the practice of automatically collecting, grouping, and analyzing those errors across your applications so you can spot patterns, understand their impact, and resolve them quickly. Rather than manually scanning logs or relying on user reports, error tracking tools give developers the context they need — from stack traces to variable values — to reproduce and fix issues efficiently.

Why Developers Use Datadog for Error Tracking

Error tracking isn’t just about catching bugs — it’s about giving developers the context they need to fix issues quickly and understand their impact. With Datadog, errors are automatically grouped into meaningful issues, enriched with stack traces, variable values, and environment details, so you can debug with confidence. Because Datadog is part of a full observability platform, you can see how each error connects to real user sessions, backend traces, and logs, making it easier to prioritize what matters most and reduce downtime.

Error Tracking supports 10+ languages and frameworks

typescript.svg
android.svg
go.svg
flutter.svg
ios.svg
cplusplus.svg
react.svg
javascript.svg
java.svg
net.svg
node.svg