The error message “Cannot use import statement outside a module” occurs when the import keyword is encountered in an improperly configured JavaScript or TypeScript module.

In a JavaScript server-side runtime environment, this error usually results from the use of import syntax for modules written in ECMAScript (ES) when Node.js is expecting the require keyword used by CommonJS module system.

TypeScript supports different module formats, but coding errors that confuse the ES and CommonJS approaches to importing modules also result in this error.

On the browser side, the error typically occurs when you don’t use a bundler for your JavaScript code files.

This article explores these three error sources and details a solution for each environment.

How To Resolve the Error in Server-Side JavaScript

This section demonstrates how to solve the error in server-side JavaScript environments.

Background

Node.js uses the CommonJS system’s require keyword by default. Therefore, you’ll receive the familiar error unless you configure Node.js to support ES module syntax. Similarly, Node.js requires the .mjs extension to recognize and work with ES modules.

Solution

As an alternative to using .mjs, you can make older versions of Node.js compatible with the current ES module by using bundlers or running Node.js with the --experimental-modules flag. Otherwise, you could set the type field in the package.json file to module as follows:

{
  "name": "test-package",
  "version": "1.0.0",
  "type": "module",
  "main": "app.js",
  "dependencies": { }
}

(Note: You should include the type property in the package.json file in all packages. This practice makes it easier to identify the module system in use and ensure consistency among your libraries.)

Another way to avoid the error is to ensure that the import and export syntaxes are correct and load properly. It’s critical to always use relative file paths, named exports, file extensions for exports, and avoid default exports.

Here’s an example:

//module import 
import { sampleFunction } from './sampleModule.js';

// function export
export function sampleFunction() {
     // code goes here
}

Finally, you should ensure the compatibility of all third-party libraries with ES modules. For this information, refer to the library documentation for the package.json file. Alternatively, use a bundler to transpile the code so a JavaScript environment can understand it.

How To Resolve the Error in TypeScript Environments

This section demonstrates how to solve the error message in TypeScript environments.

Background

With modules, you can reuse, organize, and share code among multiple files in a project. ES supports external modules for sharing code among various files using the import and export keywords.

This error usually occurs in TypeScript environments when using the ES module syntax without configuring TypeScript to use it. Since TypeScript is a superset of JavaScript, it defaults to using CommonJS syntax for imports, which uses require instead of import. In this case, the import statement causes the error. Nevertheless, correctly configuring TypeScript is necessary for it to support ES modules.

You might also encounter this error if you use the incorrect file extension. For instance, when using TypeScript in a Node.js environment with ES module syntax, the module you want to import must have the .mjs file extension instead of the regular .js.

Another common source of the error is the improper configuration of the module field in your tsconfig.json or package.json files when using bundlers like Webpack. However, you can use bundlers for ES modules in TypeScript by setting the module and target fields in the tsconfig.json file to ECMAScript. Then, Webpack will understand the target environment and use the correct file extensions when transpiling the code.

Solution

To load ES modules using a module loader like RequireJS or a bundler like Webpack, make the following additions to the tsconfig.json file:

{
  "compilerOptions": {
    "module": "es20215",
    "target": "es20215",
    "sourceMap": true
  }
}

In the compilerOptions portion of the code above, the module and target fields are set to use an es20215 module. With these additions, you can use the import and export statements in a TypeScript environment without causing the error.

As TypeScript uses CommonJS by default, failing to modify the tsconfig.json file accordingly will result in the error message.

Fortunately, once you’ve set the module and target fields to use an ECMAScript module, you can use the export statement to export a function or variable from a module and the import statement to load another module into the current one’s scope. This process occurs in the code below:

// sum.ts
export function sum(a: number, b: number, c: number): number {
  return a + b + c;
}

// main.ts
import { sum } from './sum';
console.log(add(4, 4, 9));

If you’re using an older version of Node.js, you can enable ES module support by running your code with the --experimental-modules flag. You should also use a bundler like Webpack, Browserify, or Rollup to bundle all the ES code and output it to a single file. Ensure that it’s in a version that browsers and old Node.js versions can understand and set up a Webpack.config.js file in the root of your project that specifies the module type.

Here’s an example extracted from the Webpack documentation:

module.exports = {
  entry: './src/index.ts',
  output: {
    filename: 'bundle.js',
   path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    extensions: ['.ts', '.js', '.mjs']
  },
  module: {
    rules: [
      {
        test: /.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  experiments: {
    outputModule: true
  }
};

The compiled code is output to a bundle.js file in the dist directory of the project’s root directory.

You can also use polyfills like es-module-shims to target older browsers that don’t support ES modules’ import and export statements.

How To Resolve the Error in Browser-Side JavaScript

This section shows you how to solve the error in browser-side JavaScript environments.

Background

Most modern browsers, including Chrome, Firefox, Edge, and Safari, support ES modules, so you won’t need to use browser polyfills, bundlers, or transpilers.

You also don’t need them if you use the React or Vue JavaScript-based frontend libraries because they support the ES imports and exports fields by default. However, older browsers don’t support ES syntax, so they require these tools for cross-platform compatibility.

The most prevalent reason for the error in an older browser is when a page’s HTML files do not contain the type="module" attribute. In this scenario, the error occurs because JavaScript running on the web doesn’t include default support for ES module syntax. For JavaScript code sent across the wire, you might encounter a cross-origin resource-sharing error when attempting to load an ES module from a different domain.

Solution

To prevent the module error in an older browser, ensure that you’re using the correct script tag attribute — type="module" — in the root HTML file. Alternatively, you can use Webpack to transpile the code so that older browsers can understand it.

To use the type="module" attribute, include the following line in your root HTML file:

<script type="module" src="app.js"></script>

It’s equally critical to ensure the import file paths are valid and that you’re using the correct import syntax.

Additionally, you can visit sites like Can I Use to confirm browser compatibility for ES modules.

Finally, since using the .js file extension is common practice, you can set the type attribute in the module’s HTML file script tag as a workaround. Setting this attribute to module tells the browser to disregard the .js extension and treat the file as a module.

Summary

The “Cannot use import statement outside a module” error may appear for various reasons, depending on whether you’re in a browser-side or server-side JavaScript environment. Incorrect syntax, improper configurations, and unsupported file extensions remain a few of the most common sources of this error.

While most modern browsers support ES modules, you must ensure that older browsers are compatible. Bundlers like Webpack allow you to compile all source code with their dependencies to a single output that older browsers can understand.

Remember to add the type="module" attribute in the HTML file to inform the browser that the module is an ES module. Finally, while using the .js extension for CommonJS is the default practice, you can use the .mjs extension to enable importing ES modules.

Do you have a JavaScript application you need to get online but don’t want to manage the servers yourself? Kinsta’s Application Hosting and Database Hosting platforms could be the answer. You might even combine those services with Kinsta’s Static Site Hosting to have the front end of your application served up for free.