Import statements like import { something } from ‘module‘
are a handy feature of ES modules in JavaScript. However, you may sometimes run into the error "Uncaught SyntaxError: Cannot use import statement outside a module" when trying to use import in your code.
In this guide, I‘ll explain what‘s causing this common error and walk through 5 methods to fix it. Whether you‘re working with Node.js, TypeScript, or vanilla JavaScript, you‘ll learn why this happens and how to resolve it.
Understanding ES Modules and Import Statements
First, let‘s briefly cover what ES modules are. ES modules allow you to import and export functions between JavaScript files instead of relying on global scope.
So in an ES module, you can do:
// module.js
export function sayHi(name) {
console.log(`Hello ${name}!`)
}
And then in another file import it:
// main.js
import { sayHi } from ‘./module.js‘
sayHi(‘John‘) // Hello John!
The important thing to know is that ES modules have their own scope. The sayHi
function isn‘t available globally – you have to import it to use it.
This is different than old-school scripts that attach things to the global window
object.
The "Cannot use import outside a module" Error
By default, Node.js treats JavaScript files as regular scripts rather than ES modules. So if you try to use import
or export
at the top level of a .js file, you‘ll get an error like:
Uncaught SyntaxError: Cannot use import statement outside a module
This happens because import statements are only allowed inside ES modules. Since Node doesn‘t know you want to use ES module syntax, it throws this error.
You may also see the error if you try to run an ES module file directly, like:
node my-module.js
Instead, ES module files need to be referenced by a regular Node script.
So in summary, the error occurs because:
- You‘re trying to use
import
orexport
in a regular script - You‘re running an ES module file directly instead of referencing it from a script
Below I‘ll show you 5 ways to resolve this by telling Node.js to treat your code as ES modules.
Method 1: Add type="module" to the Script Tag
If you‘re using ES module syntax in the browser, add type="module"
to your <script>
tag:
<!-- Before -->
<script src="app.js"></script>
<!-- After -->
<script type="module" src="app.js"></script>
This tells the browser to treat the JavaScript file as an ES module rather than a regular script.
One catch with this approach is that you‘ll need to run a local server. ES modules used in <script>
tags need to be served over HTTP rather than loaded from a local file.
So you‘ll need to run something like:
python -m http.server 8000
And then visit http://localhost:8000
rather than opening the HTML file directly.
Method 2: Set "type": "module" in package.json
If you‘re using ES modules in Node.js, open up your package.json and add a "type"
field:
{
"type": "module"
}
This tells Node.js to treat every .js
file in that folder (and subfolders) as ES modules.
So then you can use import
and export
directly:
// my-module.js
export function sayHi(){
// ...
}
// app.js
import { sayHi } from ‘./my-module.js‘
The one catch is that if you‘re working with .ts
files, you‘ll need to run your app with nodemon
instead of node
.
This setting only applies to .js
files, so TypeScript needs the extra step.
Method 3: Replace import with require()
An easy fix is to replace import
with Node‘s traditional require()
function:
// Before
import parse from ‘some-module‘
// After
const parse = require(‘some-module‘)
The require
function is available globally in Node.js, so it doesn‘t matter if you‘re in a script or module.
This is a quick fix, but loses some of the benefits of ES modules such as static analysis and optimizations.
Method 4: Use Correct Paths with TypeORM
If you‘re using TypeORM, make sure to reference the .js
files in dist
rather than the .ts
source:
// Before
"entities": [
"src/entity/**/*.ts"
]
// After
"entities": [
"dist/entity/**/*.js"
]
TypeORM needs to import the compiled JavaScript, not the TypeScript source code.
So point it to the dist
folder to resolve the error.
Method 5: Change Module Settings in tsconfig.json
If you‘re getting the error in TypeScript, try modifying your tsconfig.json
:
// Before
"module": "esnext",
// After
"module": "commonjs",
Set the module
option to commonjs
rather than esnext
to compile the TypeScript files into Node-compatible commonjs modules.
Key Takeaways to Resolve "Cannot use import outside a module"
To recap, here are the key things to remember:
- The error occurs when trying to use ES module syntax in a regular script
- Solutions include:
- Adding
type="module"
to the script tag - Setting
"type": "module"
in package.json - Replacing
import
withrequire()
- Pointing to compiled
.js
files rather than sources - Changing
module
setting intsconfig.json
- Adding
- For browser usage, make sure to host files over HTTP
- For TypeScript, use
nodemon
and reference compiled.js
files
Understanding what ES modules are and how Node resolves files will help avoid this common "Cannot use import outside a module" error.
The solutions above offer a few different ways to fix it based on your specific project setup.
Further Reading
I hope this guide has helped explain what‘s going on when you see this error! Let me know if you have any other questions.