How to use ES6 import syntax in Node.js
Aman Mittal

Aman Mittal @amanhimself

About: React Native & Expo enthusiast | Currently, docs maintainer at @ expo.dev

Location:
New Delhi, India
Joined:
Mar 15, 2017

How to use ES6 import syntax in Node.js

Publish Date: Apr 8 '21
164 14

A module is a JavaScript file that exports one or more values. The exported value can be a variable, an object, or a function.

An ES6 import syntax allows importing modules exported from a different JavaScript file. It is a common pattern to use modules across React and React Native applications. The syntax is composed of the following ES module standard:

import XXX from 'xxx';
Enter fullscreen mode Exit fullscreen mode

An ES module is the ECMAScript standard of working with modules. Node.js uses the CommonJS standard to import modules. The syntax for this type of standard can be described as:

const XXX = require('xxx');
Enter fullscreen mode Exit fullscreen mode

Node js doesn’t support ES6 import directly. Try writing the import syntax in a JS file:

// index.js

import { ApolloServer, gql } from 'apollo-server';
Enter fullscreen mode Exit fullscreen mode

Run the Node.js server either by using npm start or npm run dev and you will encounter the following error:

ss1

The solution to this error is in the first line of the above error snippet and is now a recommend way by Node.js. Set the "type": "module" in package.json file.

{
  "type": "module"
}
Enter fullscreen mode Exit fullscreen mode

This solution works for the latest Node.js versions (which is 15.4.x at the time of writing) and versions above 14.x.x.

ss2

What about environments using Node version lower than 14

Another solution to this problem is to use Babel. It's a JavaScript compiler and allows you to write JS using the latest syntax. Babel is not framework or platform opinionated. This means that it can be used in any project that is written in JavaScript and thus, in a Node.js project as well.

Start by installing the following dev dependencies from a terminal window:

npm i -D @babel/core @babel/preset-env @babel/node
Enter fullscreen mode Exit fullscreen mode

Then create a file at the root of the Node.js project called babel.config.json and add the following:

{
  "presets": ["@babel/preset-env"]
}
Enter fullscreen mode Exit fullscreen mode

The package @babel/node is a CLI utility that compiles JS code in a Node.js project with Babel presets and plugins before running it. It means it will read and apply any configuration mention in babel.config.json before executing the Node project.

Replace the node with babel-node to execute the server in the start or dev scripts.

An example of running Node server using npm run dev script:

{
  "scripts": {
    "dev": "nodemon --exec babel-node server.js"
  }
}
Enter fullscreen mode Exit fullscreen mode

Cover image by Jake Weirick

Comments 14 total

  • Adhy Wiranto
    Adhy WirantoApr 8, 2021

    Thanks, now I can use import without making project using React hahaha

  • Mohd Ahmad
    Mohd AhmadApr 8, 2021

    I think typescript is a better way.
    Check here

  • Mike Talbot ⭐
    Mike Talbot ⭐Apr 9, 2021

    Pretty sure you can import from files that end with an .mjs extension in node 14+

    • Aman Mittal
      Aman MittalApr 9, 2021

      Yeah, .mjs is another alternative but if one is using 14+, then I personally think adding "type": "module" in package.json is more viable.

  • Taufik Nurrohman
    Taufik NurrohmanApr 9, 2021

    How to make NPM module works both with ES6 and CommonJS:

    Create ./index.mjs for ES6 and ./index.js for CommonJS.

    // `./index.mjs`
    import foo from 'bar';
    
    export function foo() {}
    export function bar() {}
    
    Enter fullscreen mode Exit fullscreen mode
    // `./index.js`
    const foo = require('bar');
    
    exports.foo = function () {};
    exports.bar = function () {};
    
    Enter fullscreen mode Exit fullscreen mode

    In ./package.json file…

    {
      "exports": {
        "import": "./index.mjs",
        "require": "./index.js"
      },
      "files": [
        "index.js",
        "index.mjs"
      ],
      "main": "index.mjs"
    }
    
    Enter fullscreen mode Exit fullscreen mode

    Example: github.com/taufik-nurrohman/quote

    • Ranieri Althoff
      Ranieri AlthoffApr 9, 2021

      It seems a terrible idea to duplicate the entirety of the code only because of the two or three first lines.

      • Taufik Nurrohman
        Taufik NurrohmanApr 9, 2021

        Any better solution? Adding build tool to copy and convert the ES6 script into CommonJS script in the same project is too much. I do this manually since this is not a large project. I can live with that.

        • Ranieri Althoff
          Ranieri AlthoffApr 9, 2021

          Yes, that's the point of transpilers, just add a build step that converts the code for you instead of doing it manually.

          If that's a small project, and it will not be bundled into a web app (i.e. it's a Node package), then just use the CommonJS version. That's what I do in node-argon2.

  • Jordan Finneran
    Jordan FinneranApr 9, 2021

    If you want to check if a third party package supports ES Modules, I made this little tool to help

    esmodules.dev/

  • Mohamed Dahir
    Mohamed DahirApr 9, 2021

    I would like to point out that there are a couple of nuances when moving from babel-translated import syntax to native ES module imports:

    • You need to specify the extension for relative files
    • You cannot use require in your ES modules
    • You cannot use named imports to import from non-ES modules

    I'd say it is a bit messy at the moment but it is the future and we have to embrace it. For more information, See

    • Aman Mittal
      Aman MittalApr 14, 2021

      Thanks for sharing this. I'll take a look. :)

  • Swastik Gowda
    Swastik GowdaJun 7, 2021

    oh my man thank you this helped me a lot 👌

  • Swastik Gowda
    Swastik GowdaJun 14, 2021

    Isn't it better to use webpack or parcel like module bundlers ? and I guess they come with babel ?

    • Aman Mittal
      Aman MittalJun 15, 2021

      It depends in the size of the application. I haven’t used webpack + nodejs so cant say much on what plugins are included. Seems an interesting thing to delve into.

Add comment