in

How to Fix "Uncaught SyntaxError: Cannot use import statement outside a module"

default image

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 or export 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 with require()
    • Pointing to compiled .js files rather than sources
    • Changing module setting in tsconfig.json
  • 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.

AlexisKestler

Written by Alexis Kestler

A female web designer and programmer - Now is a 36-year IT professional with over 15 years of experience living in NorCal. I enjoy keeping my feet wet in the world of technology through reading, working, and researching topics that pique my interest.