"Uncaught SyntaxError: Cannot use import statement outside a module" when importing ECMAScript 6
Categories:
Resolving 'Uncaught SyntaxError: Cannot use import statement outside a module' in JavaScript

Understand and fix the common 'Cannot use import statement outside a module' error when working with ECMAScript 6 modules in various JavaScript environments, including ArcGIS API for JavaScript.
The error message "Uncaught SyntaxError: Cannot use import statement outside a module" is a common hurdle for developers transitioning to modern JavaScript development. It signals that you're trying to use ECMAScript 6 (ES6) import
or export
statements in an environment that doesn't recognize them as part of a module. This often happens when browsers or Node.js run your code as a traditional script rather than a module. This article will explain why this error occurs and provide practical solutions for different scenarios, including web browsers, Node.js, and specific frameworks like the ArcGIS API for JavaScript.
Understanding ES6 Modules and the Error
ECMAScript 6 (ES6), also known as ECMAScript 2015, introduced a standardized module system to JavaScript. This system allows developers to organize code into separate files that can export
functionality and import
it into other files. This significantly improves code organization, reusability, and maintainability. However, for the browser or Node.js runtime to correctly interpret import
and export
statements, they need to be explicitly told that the JavaScript file is a module.
flowchart TD A[JavaScript File] --> B{Contains 'import'/'export'?} B -- Yes --> C{Is it declared as a module?} C -- No --> D["Uncaught SyntaxError: Cannot use import statement outside a module"] C -- Yes --> E[Module loaded successfully] B -- No --> F[Traditional script loaded successfully]
Decision flow for JavaScript module interpretation
When the runtime encounters import
or export
outside of a recognized module context, it doesn't know how to process these keywords, leading to the SyntaxError
. It's essentially trying to parse modern module syntax using older script parsing rules.
Solutions for Web Browsers
The most common scenario for this error in web development is when you're loading JavaScript files directly into an HTML page. Browsers, by default, treat <script>
tags as traditional scripts. To tell the browser that your script is an ES6 module, you need to add the type="module"
attribute to your <script>
tag.
<!DOCTYPE html>
<html>
<head>
<title>ES6 Module Example</title>
</head>
<body>
<script type="module" src="./main.js"></script>
<!-- This will load main.js as an ES6 module -->
</body>
</html>
Loading an ES6 module in HTML using type="module"
// main.js
import { myFunction } from './utils.js';
myFunction();
// utils.js
export function myFunction() {
console.log('Hello from a module!');
}
Example main.js
and utils.js
files using ES6 imports/exports
type="module"
, scripts are deferred by default, meaning they won't block HTML parsing. Also, modules are always executed in strict mode.Solutions for Node.js
Node.js also supports ES6 modules, but its implementation requires specific configurations. By default, Node.js uses CommonJS modules (require
/module.exports
). To enable ES6 module syntax (import
/export
), you have two primary options:
1. Option 1: Use the .mjs
file extension
Node.js treats files with the .mjs
extension as ES6 modules. This is the simplest way to signal to Node.js that a file should be parsed as a module.
2. Option 2: Configure package.json
You can specify "type": "module"
in your package.json
file. This tells Node.js to treat all .js
files in that package as ES6 modules by default. If you need to use CommonJS modules within such a package, you'll have to use the .cjs
extension for those files.
{
"name": "my-node-app",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
Configuring package.json
to use ES6 modules by default
require()
and ES6 import
in the same file can lead to issues. It's generally best to stick to one module system per file or project, or use dynamic import()
for specific cases.ArcGIS API for JavaScript Specifics
The ArcGIS API for JavaScript is built with modern JavaScript practices and fully supports ES6 modules. When you encounter this error in an ArcGIS JS API project, it's almost always related to how your build process or development server is configured, rather than the API itself. The API expects to be consumed as modules.

Typical ArcGIS API for JavaScript application architecture with a build tool.
If you're using a modern framework (like React, Angular, Vue) or a build tool (like Webpack, Rollup, Vite) with the ArcGIS API, these tools are designed to handle ES6 modules automatically. They transpile your code (if necessary) and bundle it into a format that browsers can understand. The error usually arises if:
1. Incorrect type="module"
in HTML
You might be missing type="module"
on your main script tag in your index.html
file, especially if you're not using a build tool or are serving raw ES6 modules directly.
2. Build Tool Misconfiguration
Your Webpack, Rollup, or Vite configuration might not be correctly set up to process ES6 modules, or it might be excluding certain files from transpilation. Ensure your build tool is configured to handle .js
and .jsx
/.ts
/.tsx
files as modules.
3. Serving Static Files Directly
If you're trying to run an ArcGIS JS API application by simply opening an HTML file locally (file://...
), browsers might have security restrictions or not correctly interpret modules. Always serve your application via a local web server (e.g., http-server
, live-server
).
// Example of importing ArcGIS API modules
import Map from '@arcgis/core/Map';
import MapView from '@arcgis/core/views/MapView';
const map = new Map({
basemap: 'topo-vector'
});
const view = new MapView({
container: 'viewDiv',
map: map,
center: [-118.805, 34.027],
zoom: 13
});
Standard ES6 module imports for ArcGIS API for JavaScript
Transpilation with Babel (Legacy Projects)
In older projects or environments that don't fully support ES6 modules natively, you might need to transpile your code. Babel is a popular JavaScript compiler that can convert modern JavaScript syntax (including ES6 modules) into an older, compatible version (e.g., ES5 CommonJS) that older browsers or Node.js versions can understand.
flowchart TD A[ES6 Module Code] --> B{Babel Transpiler} B --> C[ES5 CommonJS Code] C --> D[Browser/Node.js (Legacy)]
Code transpilation process using Babel
While modern development often relies on native module support or build tools that include transpilation, understanding Babel's role is crucial for maintaining legacy applications or targeting very old environments. A typical Babel setup involves a .babelrc
file and a build script that runs Babel.
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": "commonjs" // Transpile ES6 modules to CommonJS
}
]
]
}
Example Babel configuration to transpile ES6 modules to CommonJS
After transpilation, your import
statements would be converted to require()
calls, and export
to module.exports
, resolving the syntax error in older environments.