NestJS & TypeORM Import Error: ‘Cannot use import statement outside a module’

Updated: January 1, 2024 By: Guest Contributor Post a comment

Understanding the Import Error

When developing with Node.js, specifically using NestJS and TypeORM, encountering the error ‘Cannot use import statement outside a module’ might be confusing. This error is commonly caused by a mismatch between the ECMAScript module (ESM) and CommonJS (CJS) module systems within your Node.js application. JavaScript initially used the CommonJS system, which is fine for server-side JavaScript, but it does not support the import statement directly. On the other hand, ESM is the official standard for packaging JavaScript code and is well-supported in browsers, allowing the use of the import and export syntax.

Updating Your Configuration

The primary solution is to ensure that both Node.js and your project configuration files correctly handle ESM syntax. With Node.js embracing ESM, you should ensure your Node.js version is up to date. After that, check your TypeScript configuration. NestJS uses TypeScript, which has its configuration file tsconfig.json. This file should be edited to include "module": "commonjs" which allows TypeScript to compile import statements into require statements which are supported by CommonJS. In addition, you need to specify "moduleResolution": "node" to inform TypeScript how to look up module files.

If your application is meant to use the ESM syntax, then you should ensure your project’s package.json has the type set to ‘module’ by including "type": "module". This might require you change your file extensions from .js to .mjs to clarify that these scripts use ESM syntax.

Correcting Source Code and Project Structure

Beyond configuration, it’s also necessary to ensure that your source code is using the correct module syntax. In a NestJS project, the source files should typically use import and export without any issue, as it compiles its TypeScript code to be compatible with Node.js’s module system. However, any raw JavaScript files in your project should also use the module.exports and require syntax if you’re sticking with CommonJS, or use the .mjs extension and import/export if you’re using ESM.

Running with the Correct Settings

Execution semantics can also cause this error if Node.js is not running the compiled JavaScript with the correct module logic. If you are intentionally using the ECMAScript module system with a .mjs extension or the "type": "module" in your package.json, you’ll need to run Node.js with the flag --experimental-modules for versions prior to Node.js 14. From version 14 and onward, Node.js has stable support for ECMAScript modules without this flag.

Working Code Example

Below is an example NestJS controller which should compile and run without the ‘Cannot use import statement outside a module’ error if the above fixes have been applied:

import { Controller, Get } from '@nestjs/common';

@Controller('hello')
export class HelloController {
  @Get()
  getHello(): string {
    return 'Hello World!';
  }
}

Make sure you have the following configuration in your tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node"
  }
}

If this is an ESM project, your package.json might look like this:

{
  "type": "module",
  ...
}

And to run your NestJS project with Node.js 14 or later:

node your-app-entry-file.js

Or with an older version of Node.js, use:

node --experimental-modules your-app-entry-file.mjs

Note that for an actual fix you will need to adapt these examples to your specfic project’s file names and structures.