DEV Community

loading...

ES6 is the Node way to go

Mrinalini Sugosh (Mrina)
Michigander who is also an enthusiast for Cloud, Python, Javscript, AI/ML, coffee, hiking, and of course dogs
Updated on ・2 min read

How many of us still use the old ES syntax in our NodeJS apps?

const express = require('express');
const app = express()

app.use(express.static('public'));

app.get('/',function (req,res) {
    res.send('ES what?');
})

app.listen(3000, function () {
  console.log('App listening on port 3000!')
})
Enter fullscreen mode Exit fullscreen mode

I bet most of us do, and unfortunately I am equally guilty of this! The reason we continue to use this syntax with node is because most templates and sample codes are based on this. But since the release of Node 14.x, ES modules is officially supported and stable. But one shouldn't migrate just because its the thing to do. Migrations often involved weighing the pros and cons. After a little research and experimentation, I have concluded that there are actually three big advantages to using ES6's import over require:

  • import helps in selectively loading the pieces of code which are required
  • import also helps in saving memory loaded onto the app
  • require()'s loading is synchronous while import's loading can be asynchronous; this provides large apps with a performance edge.

So the natural question is what would it take to use an ES6 syntax in your node project?

Let's get started!

Setup package.json

One thing to note, Node.js doesn’t support ES6 import directly. If we try to use the keyword import for importing modules in Node.js, it will undoubtedly throw an error. For example, if we try to import express module, Node.js will error as follows:
image

In order to enable Node support for ES modules we need to tweak the package.json file. In the package.json file add "type": "module" to the root of the file as such:

//package.json
{
  "name": "index",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
  "dependencies": {
    "express": "~4.16.1",
  }
}
Enter fullscreen mode Exit fullscreen mode

Then run the following command to update changes to package.json

npm i
Enter fullscreen mode Exit fullscreen mode

Update your app's code to ES6 syntax

Once we have updated our package file we have to make the relevant changes to our app's code as follows:

import express from 'express';

const app = express();

app.get('/',(req,res) => {
    res.send('ES6 is the Node way to go');
})

app.listen(3000,() => {
    console.log(`App listening on port 3000!`);
})
Enter fullscreen mode Exit fullscreen mode

Run your app and it should work with the updated ES syntax!

I recently update my demo app Random Cat Facts to use the new syntax and would recommend checking out the update ES6 commit diff for a real world example of this migration.

Thank you for following along and be sure to look out for my next post!

==== Follow me on Social Media(@mrinasugosh) ====
Dev.to: @mrinasugosh
Github: @mrinasugosh
Twitter: @mrinasugosh
LinkedIn: @mrinasugosh

Discussion (18)

Collapse
zakiazfar profile image
Mohd Ahmad

TS way is the best. Use sucrase as an alternative for nodemon and ts-node

Check how fast sucrase is
image showing speed of compilation of TS using sucrase in comparison to other tools

Collapse
w3nl profile image
Pieter Epeüs Wigboldus

Typescript or not, import the the way, it doesn't matter if you use typescript or not.
Typescript is a dialect for development, not for runtime.
I also don't build my node modules back to the old way, my modules on npm have just import/export without a build step.

Collapse
zakiazfar profile image
Mohd Ahmad

but, typescript guarantees type safety and rich intellisense, if you dont like typescript check JSDoc. JSDoc provides typings using regular JS comments so, no need for build steps.

examples

/** @type {(string|Array.)} */
var foo;

/** @type {number} */
var bar = 1;

/**
 * Represents a book.
 * @constructor
 * @param {string} title - The title of the book.
 * @param {string} author - The author of the book.
 */
function Book(title, author) {
   // your code
}
Enter fullscreen mode Exit fullscreen mode

it enhances intellisense of your code editor.
Visit for more Info

Thread Thread
w3nl profile image
Pieter Epeüs Wigboldus

JSDoc is indeed very useful for development, it's a standard for me to use it, but it's also not for runtime checking.

I made e.g. npmjs.com/package/@hckrnews/objects for type checking, but there are more packages to guarantee if the data is valid.
Typescript has some nice features, but for me there are also reasons I don't use it for node.js, and I found ways to write clean code that also guarantee that the data is valid.

Clean readable code, strict linting and good tests are very important for me.
For some it can be with typescript, but typescript don't guarantee that your code is good.
Use it if you like it, but it's not the holy grail for good code.

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

@w3nl
Agreed import is the way to go TS/JS!

Out of curiousity, what are the steps you use to import/export without a build step? I have been reading a bit of the docs and found that the two ways. Certainly curious to know your approach :)

nodejs.org/docs/latest-v14.x/api/e...

Thread Thread
w3nl profile image
Pieter Epeüs Wigboldus

I use the type field in the package.json
Than you say that es modules is your default, and if you need common js, you have to change that file extension to cjs.
(e.g. if some old package need a config file in common js format)

The greatest benefit for me is debugging information, what is going on in the dependencies.
(Packages I made and use in my projects)

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Interesting I will surely check out sucrase! I was working with esbuild earlier and was impressed by its performance compared to Babel or Webpack.

Collapse
zakiazfar profile image
Mohd Ahmad • Edited

at first I was surprised too, after checking sucrase performance

Collapse
bitfed profile image
bitfed

Yeah this is what I need. I was a hobbyist node.js enthusiast until about 2014. I'm trying to hop back in now but like you said, all the tutorials and docs are outdated! A lot of style guides are still using var all over the place. Thanks. I'm very much the type to train my habits from day 1 and besides this article haven't really found a baseline or the way forward with a Node and ES6 style guide.

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

@bitfed Yes, it was certainly hard to find a guide to this with a straightforward solution but I am so glad this was helpful!

Collapse
bitfed profile image
bitfed

I hope to see more! There still isn't an ES6 node style guide.

Collapse
patelvasu profile image
vasudev

very useful for node js development

Collapse
_mohanmurali profile image
Mohan Murali

Wow this is awesome. I didnt know that node has native support for ES modules and its so simple to implement. Thanks a ton for sharing this.

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Of course! Glad you found it useful 🙃

Collapse
mynane profile image
mynane

Very good. Thanks for sharing

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Glad you found it resourceful!

Collapse
ijash profile image
Jastria Rahmat

can it be combined? say, i got npm package that uses module.export. can it be imported by using import statement?

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Yes it should work with module.export.
Just one thing to note:
Many people consider module.exports = ... to be equivalent to export default main; That's not quite true though, or at least not how Babel does it.

ES6 default exports are actually also named exports, except that default is a "reserved" name and there is special syntax support for it as a heads up