skip to content

Node.js and its many, many new features

When was the last time you looked at what Node.js is capable of? If you're like me, it's been a while — and a LOT has changed. TSC member Matteo Collina will show us what's new and how we can modernize our projects.

Full Transcript

Click to toggle the visibility of the transcript

Captions provided by White Coat Captioning ( Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON LENGSTORF: Hello, everyone, and welcome to another episode of Learn With Jason. Today, on the show, we're bringing in Matteo Collina. Matteo, how you doing?

MATTEO COLLINA: Hiiiii, Jason, how you doing? I'm very happy to be here, on the show. Me and Jason, we've brushed a new times on Twitter. We finally met in London, so it was  I don't know, it was a show about not JS and only new things that are in the  that have been coming in the pipeline and all sorts of things, so let's do that. We have done exactly [Indiscernible] show.

JASON LENGSTORF: I'm superexcited to talk to you about this, for a lot of reasons. I've been following your work forever. I love the things you do on Fastify. You're a voting member of the TSC?

MATTEO COLLINA: Technically, I'm vicechair.

JASON LENGSTORF: Oh, cool, very cool.

MATTEO COLLINA: I don't know if that means anything. [Laughter]. Who leads the meetings and says, hello, everyone. [Laughter]. This is the technical answer. How you greet the YouTube livestream, okay, for our  I don't know  for watchers, or something, that 

JASON LENGSTORF: Got it. Got it.

MATTEO COLLINA: Quite a few people watch the Node.js livestream.

JASON LENGSTORF: I bet, yeah. So, before we get too deep into the node side of things, let's talk a little bit about you.

MATTEO COLLINA: So, yeah, yeah, absolutely. So, hello. Matteo Collina. Started doing Node back whennnnnnnn...back when Node, you know, didn't work? You know? It was 0.2. And it was absolutely insane to do Node, to run Node in production. And didn't stop. At some point, I started finding a lot of bugs. First, bugs in libraries, then bugs in frameworks, then bugs in Node and either my approach to this has been either fix or replace. And, so far, I've been able to fix Node as much as I could.
So  and there's a lot more fixes that I want to do in Node, they will break everybody, so probably can't. But, you know, Fastify was born out of my frustration with a few other very notable frameworks that you can find out there, then we have the logger, which is even more  more used and quite a lot of those things. So, yeah, that's the situation.

JASON LENGSTORF: Yeah. So, I think 

MATTEO COLLINA: Oh, wait, just one more thing. I recently  I've been a consultant for eight years and a half. Then I decided I wanted to do product and I launched the startup and the startup is called Platformatic. So, check us out. Okay, if you're running Node.js, please check us out. Even generated API clients, quite a lot of things that are quite useful. So, yay.

JASON LENGSTORF: Yeah. I think  I was taking a peek at Platformatic and it is very exciting, especially if you've been working in, like, in the team, you got to coordinate a lot of different services. I was really excited about some of the features there.
But let's talk, today, about Node.js because I think I've been using Node since about Node 6. I think that was when I really got into it, was, like, it was around the time that there was that whole split with, like, io.js. That was kind of, like, when I started 

MATTEO COLLINA: Node 6 or Node 0.6?

JASON LENGSTORF: Great question. I don't know. [Laughter].

MATTEO COLLINA: Node 6 is past the renew. This happened between 0.10 and 0.12.


MATTEO COLLINA: In fact, you know, there was Node 0.10 was the last Node released, to some extent. Now we have Node.js 1, 2 and 3. Then, the Node 0.12 got merged into the io.js tree, so reality is, we are running io.js and if you want to contact the Node.js TSC, you send an email to [Laughter].


MATTEO COLLINA: All of you are running io.js.

JASON LENGSTORF: I love it. I've been using it for a long time. I think that Node is one of those tools that's sort of a victim of its own success. These days, I hear a lot of people complain about it, but it doesn't feel like Node, like NPM. The challenge isn't that Node, itself has problems, it's there are challenges when you run an ecosystem of the size that Node has when you are dealing with the very, varied preferences that developers have when they work on tools.
But I think one of the criticisms that I had heard, about Node, that felt valid, was that a lot of things that felt like they should be built in weren't built in. You needed a Node, but you also needed [Indiscernible] and you'd always have to reach for a few more packages and so it felt  and I think that was sort of the big selling point that you would hear from any competitors to Node is, it's all built in. It's one runtime for all of it.
Recently, I was looking at Node and it doesn't  it feels like  at this point, when we criticize Node for those types of things, it sort of feels like we're criticizing a ghost because that's not what Node is anymore. That was why I wanted to talk to you is because I feel like there's almost a perception of Node that's stuck in the past, where people are remembering what it was like to run Node 8 or Node 10 and we're on Node 22 now. So, obviously, like, 10 major versions, we've come a long way, right?
[Laughter]. So, like, as somebody who's very close to the project, have you felt the same  I guess, like, I'm kind of putting words in your mouth. How have you felt about the public perception of Node?

MATTEO COLLINA: Okay, so, 90%  probably more, I don't know. I'm making a bet. I don't know. A huge number of people that use Node.js are using Node.js like they were in 2015. A few popular article and courses being written on those, in those years. And, that's what everybody's using. Okay. To be honest, this is my, um...yep. This is my  this is my take. Okay.
So, a lot of people have been using those and have been using those and creating all sorts of problems with that. Okay. So, um...basically, 2015, okay, Node became massively popular. It starts this massive growth, okay. And it's right now, no starts evolving again. It's great. Everybody gets start working on it. Okay. The success is so big that things cannot be changed anymore. Okay.
And, then, Node.js, it got stuck into the same problem of the web, in general. Okay. You cannot break the web. Okay.


MATTEO COLLINA: And Node.js is essentially stuck in that, more or less, same conundrum that you can, more or less, write an application like it's 2015 and, more or less, it will stick work in modern Node. To be honest, one of the most popular framework for Node, Express, runs the same  the same code of Express can run from 0.8 up to 22. Okay. This is level of stability of the project. Okay.
So, essentially, we have not breaken much. There have been breaking changes, new features, but the core of the project has not broken everybody. In fact, there is still very, very obscure, deprecated feature that we can't really get rid of because we will break the ecosystem, okay.


MATTEO COLLINA: Even stuff like domain, the domain module is so damn botched and it's still right there because so much of the ecosystem relies on it. Okay, which is a massive pain, to be honest.
So, we have experiments, we have experimental features, you know. When something lands, it is really hard to get rid of it. If it's popular, we start using it immediately and then if you try to yank it, you're in big trouble.


MATTEO COLLINA: So, 2015, massive popular. 2018  all across the years, massive amount of content gets produced. Okay. There is infinite amount of content everywhere about Node. For example, there is a content about all sorts of things in  in  in the  on [Indiscernible] or other platform. Okay.
And then, nobody updated that content anymore. Like, that's the problem when you write a blog post or you produce a video  and you know it very well, Jason. You produce a piece of content and that is set in stone. Why documentation on the web can be updated, a blog post or a video, it cannot. It has a course. It has a time to live, right. It has a freshness aspect to it. Problem being, you know, I was checking recently and somebody said it's being  we're publishing the same stuff of years' past, changing the year.

JASON LENGSTORF: Interesting. Okay  and actually, this brings up a really valid point because one of my most popular videos I released was from 2016 and that is how to build a Node server and that still gets traffic today, despite me having released, in the meantime, like, I just wrote a new post, within the last few months, about how to set up a modern Node server with TypeScript today, which has one dependency, which is TS Node but the one I wrote in 2016 has a bunch of dependencies because those features weren't bit in. The one I just wrote isn't getting the pickup that the one in 2016 did, so how do we solve this problem? That's a really valid point.

MATTEO COLLINA: This is the main concern is, the Node.js project is shipping stuff, doing stuff and producing new things. Nobody give a damn thing about anything. Okay. You keep writing software, like it's 2015, okay. And, like, one example  I'm just making one example, okay. One of the biggest problems that we had in 2013, 2014, 2015, those years, was that the support for WebSockets were not widespread, okay. And Socket.IO was one of the biggest solutions because it removed the problem and said, you can use allvalue systems and it will create the level of interactivity that you need. Great project. Okay.
However, now, WebSocket is everywhere. Okay. And yet I'm still seeing blog posts being published, content being published, video being recorded how to use Socket.IO. By the way, it makes absolute no sense to use Socket.IO in 2016. This is all few that are listening. This is just one example of a phenomenal, popular module that was great. It solve a very specific problem back then. Now, everywhere, we have WebSocket and it's working very well across all proxies, CDNs, so there's absolutely no need to use that. The support for it is rolled out across all proxy servers, there's no need to punch that wall anymore.
That's to make an example of one of the things that are bad in there, okay. And still publish  Node.js can release a lot of things but one of the reason I wanted to be on this call is to talk about what's new, okay. Because a lot of people don't know, they're still doing 2015.

JASON LENGSTORF: Yeah. And I guess this is the other problem, too, is that that body of work, then, what Ester's saying is ChatGPT will tell you to use Socket.IO. [Laughter]. That's a very, like, good  kind of an encapsulation of the challenge that we face, is that if we're not actively looking at what's going on with the project, itself, then we run the risk of falling into habits that were valid at the time, but aren't valid anymore. This is like jQuery, it was a giant leap forward ahead. Continuing to use jQuery is fine but you don't need to, it's extra work for no real reason and that  you know, and that was the stated goal of jQuery, we want to solve this problem until we don't have to and then we'll fade away.

MATTEO COLLINA: It never did. [Laughter].

JASON LENGSTORF: It never did. It's still on something ridiculous, like, 70% of the web.

MATTEO COLLINA: And you don't know much  what's the build for the CDN, by the way. Everybody using CDN. I don't remember who does it, they give the project for free, otherwise the build will be incredible. So...


MATTEO COLLINA: I'm also part of the OpenJS board. I oversee all the projects, including jQuery, Webpack, Lint. We talk about budgets. [Laughter].

JASON LENGSTORF: As  as it tends to go. But so  so, you know, knowing, then, that a lot of the articles and tutorials might be, you know, presenting information from 2015, as opposed to, you know, 2024, like, what are we missing? You know, I was pretty surprised when I went into the Node docs and I realized there were a bunch of features people weren't talking about. I'll drop the link in case people want to see it. This is one of those moments, the light bulb came on and I was like, wait, I'm pretty sure all the things I think about Node are outdated. I'm pretty sure those problems have been addressed in the project and then I got into the docs and started looking around and realized, yeah, in fact, that's true. It's like a whole, new tool. The things that used to be really painful, like, managing ES Modules, it kind of works now. It's just there. [Laughter].

MATTEO COLLINA: It's just there. It's just there. And it's slowly getting better and better. We are plugging all the holes, essentially. And finding new bugs, it's actually very, very tricky. So, it's really, really  it's really, really nice. So, um, yeah. I  I really like it, to be honest.
So, part of  so, right now, I was starting with one of the Platformatic clients today. One of our customer. And they have this fantastic setup, which they do  the Node.js runner. They use TSX and they use the loader system so that they  they write  it's all TypeScript. It's all TypeScript, but they just transpile it on the fly, using Node Test Runner and things absolutely so speedy and super, super nice, like, you run it and the test runs instantaneously. You make a change, it automatically restarts itself.
It's a completely new  it's a brandnew word, essentially, on those things. It's really, really, really, really nice.

JASON LENGSTORF: Yeah. And that's kind of what got me  that's what got me thinking I needed to talk to you  or somebody else  on the Node team. It just feels like we're being  we're not measuring Node on its merits, we're measuring it on its history. That's just kind of a bummer of a way of dealing with software projects because every project had issues when the platforms couldn't support these things. Socket.IO existed because WebSocket support was janky. If we held everybody to that standard, of what they could do in 2014, it's like, yeah, we're not going to make any progress ever.
Let's see if we can stand up a project and start using some of these features and see how far we can get without adding dependencies or very minimal dependencies.

MATTEO COLLINA: Absolutely. Ooohhh, my light is gone. [Laughter]. That's fine, don't worry. So, I need to move the screen so I'm not going to look at you anymore, just so that you are aware. I'm just moving the screen and putting it on the other monitor so you can see  I don't  I have a muchless fancy setup than you do, okay. And, I  I have this, so I need to  so, this is the camera and  but I need to look here.

JASON LENGSTORF: Now it looks like we're both  we're both looking at the code now. [Laughter]. Okay. So, when  before I start, let me do a quick shoutout. Thank you to our sponsors, Nx and Netlify. We have Vanessa, from White Coat Captioning, taking down all of these words into the link before. If you need the captions, they are there for you. And that is, you know, very much appreciated.
And then we are talking to Matteo...


JASON LENGSTORF: And your Twitter profile is here. Let me drop a link of that into the chat.
We are talking, today  let me get over to a cleaner page. We're talking about Node.js. So, here is...the Node.js home page. I'm on 

MATTEO COLLINA: We shipped a new website. Come on!

JASON LENGSTORF: Yeah, you shipped a new website. And  I checked this out, branding. Look at this. Look at this amazing thing, that has happened. Node got a mascot. There's really  like, the potential for criticism is vanishing quickly. You got a great mascot, you got a new website.

It's also modern. The website was so clunky, okay. Took forever to ship this.

JASON LENGSTORF: I can imagine because there is a ton of information on this site.
Okay. So, if I want to dig in here, and I want to try the modern Node, what should I do first?

MATTEO COLLINA: Okay. You should have Node installed. There's still a lot to go, okay. You should have a terminal, okay. And you should have something like NVM.


MATTEO COLLINA: If you don't have it, you are in trouble. You should be installing Node using NVM. If you are on Mac or Linuxbased system, otherwise, you are absolutely  it's not going to work. Okay.

JASON LENGSTORF: It's going to be challenging.

MATTEO COLLINA: Yes, bigtime. There are ways you can get a good, decent Node.js installation, but, nope. This is the only one that  it's simple, you know. It just works out of the box. We have Node.js 22. So one of the first thing that a lot of people complain about, okay, you have, have specific  one of the complaints is Node.js is slow. Okay. And low start, low boot time. Okay. Node.js 22.1 shipped a fantastic, new feature, okay, called Node_cache. If you go  this was just announced, okay, in the latest  this is, you know, literally the latest release. And, it has Node_compiler. If you run this on...on  on your app, you can see that it starts so much faster. Okay. You know, let's give that a very simple try, okay. Can you write a TypeScript file?

JASON LENGSTORF: Okay. I'm going to do an index.ts.

MATTEO COLLINA: Put another word in there, that's fine. Yep.

JASON LENGSTORF: So we're going to go with a console log.

MATTEO COLLINA: Yeah, just do that. And now know, time. And space, NPX. Oh, no, sorry. You need to  sorry about that. You do an NPM and TypeScript, otherwise it's not going to work.

JASON LENGSTORF: Okay. We'll call it here. Go through all these, good.


JASON LENGSTORF: Ts Node or TypeScript?

MATTEO COLLINA: TypeScript. Now let's try that. You do "timenpxtsc."

JASON LENGSTORF: 0.5 seconds.

MATTEO COLLINA: Yeah. Do the same command, but add Node _module. Equals [Indiscernible] tmp/node. And the same command.

JASON LENGSTORF: What did I do wrong? Time, NPX.

MATTEO COLLINA: Do an export.

JASON LENGSTORF: Right, right, right. I know how Bash works.

MATTEO COLLINA: Sorry about that. You need to do the export and do runtime.

JASON LENGSTORF: I gotcha, I gotcha. Let's see, that was 3:38 total.

MATTEO COLLINA: No, it's not picking it up. You need to go up the one it was at the beginning.

JASON LENGSTORF: The one that was at the beginning.

MATTEO COLLINA: The first one. Very  it's not picking it up.

JASON LENGSTORF: Let me make sure that this is actually picking up...well, actually, is this where that's why.

MATTEO COLLINA: Put "/tmp." You can just put it there. You can just put it on the local thing.

JASON LENGSTORF: Okay. If I can spell right. Okay.

MATTEO COLLINA: Redo the export and...

JASON LENGSTORF: And, we'll go to cache...


JASON LENGSTORF: And that again.

MATTEO COLLINA: It's not picking it up. Pretty sure. Do Nodev. Try doing Node..._modules.bin.tsc. Yep. Run this. Run it with time at the beginning.

JASON LENGSTORF: That was a lot faster.

MATTEO COLLINA: Yeah, told you. [Laughter].

JASON LENGSTORF: All right. All right. This is  this is very quick. So then we're  we're looking at 

MATTEO COLLINA: What is happening here, for some reason, this caching is not working through NPX. But if you look inside the Node 

JASON LENGSTORF: What was it called? Node Modules Cash?


JASON LENGSTORF: I also feel like I'm not getting this to work.

MATTEO COLLINA: I don't know why it's picking it up on the export.

JASON LENGSTORF: I have a hunch  maybe we can put this into...let's go Node Modules Cache. Nah, this isn't going to work. All right. So, this is my fault because I  my  my Bash is so jacked up from, like, the million things that I install every week so I'm pretty sure 

MATTEO COLLINA: Try running it on the same line. Node.modules.cache.equals.

JASON LENGSTORF: This was Node and we're going into Node Modules. And that's it.

MATTEO COLLINA: Yeah. Okay. This is running.

JASON LENGSTORF: Okay. So that's running.


JASON LENGSTORF: Do I need to put the time in front?

MATTEO COLLINA: No. Try putting the quotes between the .cache. Time needs to be there. Yeah.


MATTEO COLLINA: I don't know why your system is not 

JASON LENGSTORF: It is fighting me.

MATTEO COLLINA: I have no idea what you've got on your Bash, man.

JASON LENGSTORF: It's a mess. [Laughter].

MATTEO COLLINA: Sorry. It's the wrong variable. It's Node Compile Cache. Do an "export node compile cache." Try that. I don't know why your Bash is.

JASON LENGSTORF: I'm pretty sure if we 

MATTEO COLLINA: "Node compile cache."

JASON LENGSTORF: There it goes.


JASON LENGSTORF: Heyyyy. Now we're cooking with gas.

MATTEO COLLINA: No, no. Wait a second. It went for 120 milliseconds to 018.

JASON LENGSTORF: It went 75% after we hit that cache. So that's  that's ridiculous. And then it gets  yeah. It sits right around, like, .06.08.

MATTEO COLLINA: Try zapping the cache. Rm.rf.cache. Run it again.

JASON LENGSTORF: 127 and then we run it again and now that it's cached, it's fast.

MATTEO COLLINA: You need to run it a few times.

JASON LENGSTORF: It's about .08. That's a 30percent improvement? 35%.


JASON LENGSTORF: Yeah. And, like, we're literally parsing a Hello World here.

MATTEO COLLINA: This the TypeScript. This is the TypeScript executable. You're not running that.

JASON LENGSTORF: Oh, it's not parsing this one for us?

MATTEO COLLINA: You need to execute  do the compiling. I don't know why it's not picking it up. I don't know why TSC's not compiling it.

JASON LENGSTORF: There we go. That picks it up and now that's .4 and then we run it again.

MATTEO COLLINA: Zap the cache. You're running the full project. So...

JASON LENGSTORF: And then run it like this?

MATTEO COLLINA: This is without the cache.


MATTEO COLLINA: And then you're doing it again. You get that, I don't know, 3050 millisecond out of the way on startup. The more modules you load, the bigger this becomes, the more benefit you got. So, this is  now, this is  we got that out of the way. Let me show you something so nice.
If you go install TSX highlight. You can use TS Node, but I don't know the syntax.


MATTEO COLLINA: Yes. It's superfast. What you could do, for running your index.ts file, you could do "nodeimport=tsx." Yep. And you put the index.ts file.


MATTEO COLLINA: You can do with Watch.

JASON LENGSTORF: Oh, right. If I come in here...look at that, y'all. We didn't have to install  I don't know how to pronounce it. Nodemon? They trolled in the "About" for it. I was like, come on, give me an answer. [Laughter].

MATTEO COLLINA: You can have a selfrestarting system. You have this without anything  you know, if you use TypeScript, you will have to use a compiler. Okay. And, Node.js is not going to ship a TypeScript compiler within Node. Okay. One, specific reason is the TypeScript team does not recommend it to. Why? Because Node.js  because TypeScript is, uh, phenomenal, like, saying the TypeScript is a language, it's not necessarily correct. TypeScript is  I call it a multiverse of languages. If we added to include compile TypeScript by default, we will have to define, in stone, what's the config, like Dino has done.
My friends at Bloomberg, the first thing we did, this is the "ts.configure.json" for the company. We are likely to do that for all the Node.js users because there is a special relationship between TypeScript and Node. This is one of the critical things we are not shipping so you still need to install TypeScript or TSX or TS Node.
Let's do a change. In this thing, we can add a type module because we really like ESM. Or, actually, even, remove that. Scrap that. We're done with it. Now, create a new file, over there, called "serving.js."

JASON LENGSTORF:  .ts or .js?

MATTEO COLLINA:  .js. Here, you use import. We're not doing anything. You can do import, okay, and you  let's do "import create server." You need to extract it.

JASON LENGSTORF: It's a named one?

MATTEO COLLINA: Yes. From Node. They decided to put the Node prefix in there. Essentially, a right of firstchoosing on names, we can never overwrite everybody. We did that.

JASON LENGSTORF: That's a good move. What is 

MATTEO COLLINA: You need to put a handler. You still use events. On request, unfortunately. Like, a lot of people don't know this. So, Server  you need to put "server.on." And "request." And  all function requests and response.


MATTEO COLLINA: Very oldschool.

JASON LENGSTORF: And so I can do something like 

MATTEO COLLINA: You want to respond so you do "console log." Yep.

JASON LENGSTORF: And then we return 

MATTEO COLLINA: No, you can't. This is part of the stuff I want to change 

JASON LENGSTORF: Oh, right. Right. You need to request. The first one is the request. Yep, exactly.

MATTEO COLLINA: That doesn't exist. "End.send." This is the part that we did not improve. This has been the same since ever and ever so we didn't break you. This is the reason you can run your project for 2015 and it will still work just fine.
Now, what's actually cool here is, now you have to actually start your server. You know you called "server.listen," as you've always done...

JASON LENGSTORF: Server.listen.

MATTEO COLLINA: And you put in your port.

JASON LENGSTORF: We'll do 3000 because that's the classic. Now do I just Node server?

MATTEO COLLINA: It will throw a big error to you.

JASON LENGSTORF: Okay. Let's look at big error. "Cannot use import statement outside of a module." We're using the import syntax instead of the Require syntax.

MATTEO COLLINA: You have a flag. You go back in your terminal. You can do Node.js, at the top, before "server.js," you need to put, before "server," "experimentaldetectmodule."

JASON LENGSTORF: Ooohhh. Cooool. Okay. So, then, head over, here, we'll go to Localhost 3000. And it sends back...our response here. And then I've got my request coming in there, as well? Dope. This is great.

MATTEO COLLINA: Okay. The other big thing that everybody is complaining about, okay, is require ESM. And this is part of what was shipped in Node 20. Okay. Which, it's actually quite nice. So, let me  okay. So, what you can do, for example, let's say that you want to, know, write  copy this module and let's do a CJS version of it. Okay.

JASON LENGSTORF: CJS version of this?

MATTEO COLLINA: Index.js. Yep.

JASON LENGSTORF: And you want me to do it as, like, a .cjs?

MATTEO COLLINA: Yep. Sorry. I did a mistake. Okay. I wanted the server one, not this one.


MATTEO COLLINA: Let's do a CJS version of it. Let's say you want to  you know  yep. Go back  yep.


MATTEO COLLINA: And this is what  yep, exactly. This will work, the exact same thing. Okay. This is nice. Okay. Now, you run this. You can run this and now, what you can also do, okay, if you create another file called "foo.mjs." It's a module. A lot of people, you started publishing modules as ESM. Here, you do export "export function," yep. And you  yep. That's fine. Yep. So, in "server.cjs," this is our server, what you can do, now, we can do "const."

JASON LENGSTORF: Call it "something."

MATTEO COLLINA: And you can require that file.

JASON LENGSTORF: That's exciting. We had to do an "await import."

MATTEO COLLINA: Yep. Passing in the flag...yep. And now if you run this, this will not work, you need server.cjs. And this will not work because it's  you're missing something. Okay. Still a new flag, it's called "experimentalmodule."

JASON LENGSTORF: Okay. I guess we don't need the "detect module" this time, do we?

MATTEO COLLINA: No, we don't. Now, it actually works.

JASON LENGSTORF: It works and we get our ESM. This is going because we're also sending it to a web browser so we send an options request and do a "get request." So that's why we're getting multiple requests coming through.

MATTEO COLLINA: You've got two because of the [Indiscernible] request. You got your requests. So, it's  it's pretty nice. Okay. You can get this done pretty quickly.

JASON LENGSTORF: I mean, this  this. So, two things that I think are worth kind of pointing out. Huge complaints in the ecosystem have been about the  the challenges of common JS and ES Modules and the interoperability of the two. No dependencies, other than TypeScript, we have one ES version where we're running this server as an ES Module, and we are importing it, all working in Node with no parsing, no transpiling, no detection, no webpack, no anything. It just works.



MATTEO COLLINA: And I want to thank all the people who made it possible because it's not that  all of these came for  like, all of this came from a lot of sweat from a lot of people. Okay. And it's  it's actually quite insane how  the fact that all of this works in this way and it's  it's been a [Indiscernible] effort. You need to have this support on top of existing things. It's not about  everybody wanted to do this from the beginning, okay. The problem is that there was a lot of other challenges that we have been able to overcome, okay, in the latest few years.
Like, you would imagine that we broke everybody. Everybody was so damn pissed at Node team when we changed the Loaders format last year. Without that specific change, these things would not have been possible. So these things  a lot of people say, Node.js has done this because x did something or y did something else. More or less, a lot of this stuff were in the plans, okay. It just that, um  like, the idea of people, but we were blocked by certain changes. Okay. So, moving the loaders to another thread allowed us synchronous communication with that. So we could actually run a lot an asynchronous loader while doing a Require ESM and blocking the main thread because the loader can run asynchronously on the other side. It's pretty cool.

JASON LENGSTORF: Really, really cool stuff.

MATTEO COLLINA: All of this is actually freaking complex. It's really, really complex.

JASON LENGSTORF: Yeah. I mean, the  the  sometimes, I get  I get a wild hair and I tell myself I'm going to go mess with an AST transformation so I can get a little bit of code and do something magic and I realize how deep this rabbit hole goes. I'm just trying to get an image tag from Markdown to HTML and the folks working on these lower levels are literally transpiling formats from one completely incompatible spec to one that is completely seamless. This is some  some absolute [Indiscernible] magic.

MATTEO COLLINA: The point is doing it without breaking everybody. And support all the use cases people want to use ESM with. So  and, you know, if ESM was built to only be executed synchronously, you will not have an "await import." You just have an import. In fact, all of these also work, for example, with Remote Loading of software. You can actually remove  load the JavaScript file from an HTTP source. I haven't tested it. This is the [Indiscernible] there is a lot of fear and you can explain all the things. It's in very great details. Okay.
And, basically, the spec was bad. Then in 2019, the spec was fixed. Then...the word went kaboom, there was a lot of shuffling on the project and [Indiscernible] picked up the threads and thanks to, I think, Bloomberg, who funded their work for this. There was somebody that put the money where their mouth was and 


MATTEO COLLINA: And funded the work because Node.js is a project run by volunteer. We don't have magical money. Platformatic has magic money, we are trying to build a company. Node.js is not a company, it is a group of volunteers. People  if you want to make something happen with Node, you need to do it. If you need to spend, I don't know, a month doing something, somebody needed to pay for your bread. If you're employed with a company, some margin for your employer, too. So, um...yeah. Thanks to all the people that contribute to Node and fund Node.js work. If you are a company that are watching this and you say, I have a bug with Node, I want it fixed, maybe ask, how can we get  how can we pay somebody to do the fix? Okay. Essentially. This is a very, very important part. How can we pay somebody to do the fix for us or? How can we send the money?
If you ask, or something, it's  and by the way, it will be fantastic to a lot of $10 sponsorship. But, to be honest, $10 sponsorships are not necessarily  you need a lot of them. A huge lot to start making the dent. Okay. It's considered that Node.js, right now, as more or less, something around 100 collaborators working on it and maybe 50 very active ones so there's a lot of people working on this every single day and a lot of them are just literally working to keep the lights up. We're not talking about security.
Something I want to show you about a couple other features we shipped, in the last couple of years, go back to the Node.js one because I like it. Okay. Now, a very interesting feature is in the util modules, two features, okay. If you go in the util module, you can see there's been a few very nice things being shipped. So, the first one is Parse Args.

JASON LENGSTORF: Is it "util" or "utils?

MATTEO COLLINA: Parse Args is what you use to parse the argument of your code that are coming. So, you can do, for example, something like "const." You can copy. It's probably quicker than me telling you. So, you can just copy that. Okay. I just pasted it in the chat.

JASON LENGSTORF: Oh, you put it in the chat. Okay.

MATTEO COLLINA: You can go into the first link. There's stuff you can copy.

JASON LENGSTORF: Okay. Great. So, then we're going into Parse Args.


JASON LENGSTORF: So we get Parse Args.

MATTEO COLLINA: Yep. And then you can copy something like that.

JASON LENGSTORF: Okay. And now this, here, these options, this is, like, validation?

MATTEO COLLINA: Yep. And parsing.

JASON LENGSTORF: Oooooooohhhhhhh. That's  okay. So, then  [Laughter].

MATTEO COLLINA: A lot of people  again, it's  again, blog post from 2015. So, now you can  you need to  inside Args, you need to put  you can just delete that line. Instead there, you can do...process.arg.

JASON LENGSTORF: What is happening?




JASON LENGSTORF: Okay. And so here, I go, server.js, and I can say 

MATTEO COLLINA: Foo. That will not work.

JASON LENGSTORF: That one doesn't work. I did it wrong.


JASON LENGSTORF: Oh, it  [Laughter]. It worked because the validation is there so, if I do one of these and I make this into a it'll work because we put the validation together.


JASON LENGSTORF: Oh, my god. This is incredible. We used to need yargs. There were whole packages dedicated to this. Yeah, yeah. And so, to have this just built in, that's a gamechanger because now to build a CLI 

MATTEO COLLINA: Even better, what you can do is use another thing in util, which is Type X.


MATTEO COLLINA: Let's say that you want to create your chat message, you do "style text." It's a function, so you put in the color that you want. So, let's say, you say green. And then you can do "values.i," I think?


MATTEO COLLINA: Values. Let's try that. Remember what was in the  yeah. Let's run it.

JASON LENGSTORF: Oh, no, look at that. Holy crap.

MATTEO COLLINA: If you put that inside an array, the green, if you put the 

JASON LENGSTORF: Green inside an array. Got it.

MATTEO COLLINA: Then you add a comma and you got a string, like, underlined, under  underline. Yep. Try again...

JASON LENGSTORF: Like, I mean  this is  this is exactly what I loved about how jQuery influenced the browser, we saw what everybody needed out of JavaScript and that got built back into the browser, the platform. This is the same thing. Node, everybody was using Commander Yargs, everybody was using Chalks. Everybody was using all these different packages. You can look at  I don't know how common this is, cow paths. If you observe where the cow paths are, that's where you lay down, like, structure and so you bring that in and you make that possible so now we don't need all of those  like, the amount of effort that I have spent trying to figure out what the best package is to do colored text, what the most uptodate way to do command lines 

MATTEO COLLINA: Sorry. The funnest part of this is there was so much pushback on shipping because they were rightfully, a little bit concerned that their module would be affected. Okay. Now, part of this is, everybody like color text. So, at some point, Node.js decided, well, we need this feature in so we actually need to produce color text. Okay. And after we got the feature in, then the question was, well, you know, we might as well make it public.


MATTEO COLLINA: So, there is that. Okay. Um, so, I  like, this is a lot to talk, probably, about the test runner, okay, too. It's pretty cool. I don't know if you want to go there. Before we go there, though, I want to show you a couple of other features.


MATTEO COLLINA: So let's do another bit of a fun example of something nice. So, one of my personal pain, in ESM, when doing ESM, was getting the current directory. I could never remember how to get it. How could I get the current directory of an ESM. Do you know, Jason?

JASON LENGSTORF: I don't remember how to get  I knew how to get the directory in CommonJS but not in ESM.

MATTEO COLLINA: You can do "console.log." No need to import anything. Console.log.[Indiscernible].

JASON LENGSTORF: We just get it now? Oh, that's huge. Also, look at this, we get process and the import.meta in the same file.

MATTEO COLLINA: Process was always there. You don't get "require."

JASON LENGSTORF: Oh, that's cool. So then, down here we've got 

MATTEO COLLINA: Go up. Go up. Now we're going to use a new feature that ships in 22. Go at the top and you do...go up at the top, "import." I named ours "glob." From Nodefs/promises. This does exactly what it says it does.
Over there, you go  we glob this. We want to glob that thing.

JASON LENGSTORF: I need to await it?

MATTEO COLLINA: No, you don't. No, no. You do very nice "for await." Okay. It's not, "for await."

JASON LENGSTORF: Wait, wait, wait. "Const file of"?

MATTEO COLLINA: Glob. And await after the parenthesis at the beginning. Before, sorry, the parenthesis at the beginning.



JASON LENGSTORF: And, we can style this up. Look at it go. Here we go.

MATTEO COLLINA: Let's try that.

JASON LENGSTORF: Okay. So, now, I'm going to restart it...

MATTEO COLLINA: This is  this is fine. We need the glob patterns so you need to [Indiscernible].


MATTEO COLLINA: After that, you need to add a string. Unfortunately, you need to concat that. You need a "path join."

JASON LENGSTORF: Let's do it this way.

MATTEO COLLINA: You want the slash. You are missing a slash. Yep.

JASON LENGSTORF: Okay. So then we do one of these and, holy crap, look at us go. We've got  this is awesome. Like, this is  this is great because these are the types of things that I'm always trying to do. I want access to the file system. I want to, you know, print something out that looks like. There's a million things that I need to do, when I'm building a CLI or I'm working in one of my backend services and knowing that this is just built into Node 22 and beyond  this is all 22?

MATTEO COLLINA: All of this is in 22. It's  some of it will be backported. Some of it can't be backported. It's a hitormiss.

JASON LENGSTORF: Gotcha. Gotcha. This is slick. This looks fantastic. Okay. And so I just  we got about 15 minutes before we'll have to start winding down and I know you wanted to look at the test runner.

MATTEO COLLINA: There is one more, uh, thing I want to show here. Okay.


MATTEO COLLINA: Remove the "//." Remove the server. Document it out so at least it's  yeah, okay. Perfect. It's fine. So we just get the output.


MATTEO COLLINA: Yep. Here we go...okay. Okay. A few files. Okay. So, let's say that we want to read the files. Okay. I want to show this to you because it's actually quite  what you will do oldschool is different from what you will do it today. This is not necessarily new stuff. This is stuff we shipped around 20192020. But a lot of people haven't realized this is possible. If you go at the top, okay, you add  we add  we add "import create read stream," as a named import, from "node fs." If you scroll down, now we have the path. If the file ends with .js, "if files ends with .js." And remove the dot. We have a bunch of files.
You can do "conststream=createstream." We want to read all the chunks and make it capitalized. Okay. To do that, oldschool, we'll say "use on data." The output will be garbled. However, we can process them onebyone so what you can do is, um, "for await." And "constchunkofstream." And then you can do console log and use the green color so now we can do  "chunk.tostring" and "uppercase," or something. Let's try that. [Laughter].

JASON LENGSTORF: Look at it go. Oh, my god.

MATTEO COLLINA: The amount of code, these five or ten lines, the amount of code these replaced 

JASON LENGSTORF: I mean, it's incredible. Like, the  these are the sorts of things that when I was getting started in Node, and I would try to do something where I was reading files or I was getting into the file system, this was the stuff that always tripped me up because there were a lot of packages I needed and I was jumping between docs and unless they were using the stack I was using, I would have to think through how to match the code. The fact that this is all part of Node now, it makes it much less intimidating and it makes me  I'm lesshesitant to reach for this type of solution now. I can just, oh, yeah. I can just grab the contents of that file because it's six lines of code. [Laughter].

MATTEO COLLINA: Yes. And you can  and, we have also a tool called Watch that works in the exact similar way. If you  not this one. Sorry.

JASON LENGSTORF: Not this one?

MATTEO COLLINA: If you go to the top of the same file, next to "glob," "comma watch." And now you can, if you  scroll, command that line and duplicate that line. Put "glob" on the previous one so we don't lose it. Command 20 out.


MATTEO COLLINA: And remove the "**"at the end. Now it stays up because the files is  is watching. Now, save this file...oh.

JASON LENGSTORF: Text argument must be of type string.

MATTEO COLLINA: What we did wrong? No, no. Scroll down...

JASON LENGSTORF: The text argument must be of type string. 22. I know why.

MATTEO COLLINA: That's an object.

JASON LENGSTORF: That's just me, trying to consolelog something that can't be.

MATTEO COLLINA: File.filename. And import.



JASON LENGSTORF: And then down here 

MATTEO COLLINA: You never reach.

JASON LENGSTORF: See...incredible. Like, this is  this is  this would be so hard 10 years ago.

MATTEO COLLINA: Yeah. Don't  you know, don't  [Laughter]. No, no. Sorry. This is just hard, like, two years ago or three years ago and not ten. So, this is  it's actually pretty cool, okay. It could build up a lot of these capabilities, stepbystep, and a [Indiscernible] is actually the correct feeling that I want to  that I want to pass, okay.
So, I want to spend, I don't know, 1015 minutes T. It's  let's take  let's write a very simple file to do an addition. Okay. Something, like, a file that does 2+2. You can write in Java in TypeScript, if you like. This is fine. Write a test. This module is fine. Okay. We 

JASON LENGSTORF: Do the  do the test here?

MATTEO COLLINA: No, write a new file called  create a new folder, sorry. Call it "test." Okay. And then you  yeah, whatever you want there. I don't care.

JASON LENGSTORF: Is the test written in TypeScript?

MATTEO COLLINA: Yeah, yeah, no, we are going to use the new import  the loader. So, we do "import test." From "Node column test." Yep. And then we import that module. So, "import foo." need "" Sorry.


MATTEO COLLINA: This is fine.


MATTEO COLLINA: Then, you can do "test."

JASON LENGSTORF: Let's have this one actually return something.

MATTEO COLLINA: Then you can do "test." And, something, for example. And pass a function inside to it. Yeah, you can use error function, if you like it. If you're crazy, like me, you can not do that.
Then, you do  we need an assertion. You can use whatever you want. But we have the Assert Module in Node. You do "import." It's not a name thing. You can do "assert." And "fromnode:assertionstrict." And you see TypeScript is complaining because it doesn't know about this module. You want "assert.equal."

JASON LENGSTORF: Assert.equal. Okay.

MATTEO COLLINA: Now, we do in the main folder  sorry, in your console, you do "nodetestimport= tsx." Run it. Oh, it didn't run anything. Unfortunately, there's still a bug. You need to "test star."


MATTEO COLLINA: Look at how fast it was.

JASON LENGSTORF: Ridiculouslyfast.

MATTEO COLLINA: [Indiscernible].

JASON LENGSTORF: Right. Right. And so this is what we get when it doesn't pass.

MATTEO COLLINA: Also does with "watch."

JASON LENGSTORF: Oh, I can watch this? Oh, oh, yeah, let's watch this. Okay. So, this one is failing.


JASON LENGSTORF: So then I fix it. "Test did not finish before its parent and was canceled."

MATTEO COLLINA: Wait, let's see...oh! Because you are doing  sorry. Scroll down. This is okay. Sorry, I need to see the index.ts.

JASON LENGSTORF: Index.ts. So, "test did not finish before its parent and was canceled." So is that because this is async?

MATTEO COLLINA: No, but it's fine. Should be fine. Remove the async, but I don't think it'll change anything.



JASON LENGSTORF: Do we need to await this?

MATTEO COLLINA: That's not the problem. It's, um...

JASON LENGSTORF: But it doesn't do that when you just run it straight, so it's something in Watch.

MATTEO COLLINA: It's something in Watch, that is  the combination of TypeScript and Watch is still  they import in Watch. Okay. It's tricky. Okay. Um, yeah. To be honest, it's  in theory, you can. In practice, bugs. [Laughter]. I am  I am 

JASON LENGSTORF: I mean, the cancellation of the test file, itself, is, like, okay, if you know that that's what you're doing, you know you can ignore that.

MATTEO COLLINA: Now, one more thing here, that's very nice, you can pass arguments to that function. So you can, for example  for example, if you run in your code  sorry, in your terminal, in your console, run it with "only."


MATTEO COLLINA: Now, nothing's running.


MATTEO COLLINA:'s  like, if passing the actual file, okay. "only/index.ts." Because all of these is because there's no  it's  there's nothing. You can add "only" as an option after  no. Yeah, that will work. Yeah.

JASON LENGSTORF: And there it, basically  and then, does that change if I do this, here?

MATTEO COLLINA: Yeah. No, that tells you, you have specified "only."

JASON LENGSTORF: Oooookay. Okay. Yeah. So, it'll run everything if you have "only." But if you want to isolate a test, you can add the ".only." That is real slick.

MATTEO COLLINA: It's a feature everywhere. I use it all the time. Okay.

JASON LENGSTORF: Is this the sort of thing  yeah, it's built in. Is there an inverse? I can say, I know this test is broken skip it.


JASON LENGSTORF: And then, with this one.

MATTEO COLLINA: It's skipped.

JASON LENGSTORF: And we're on to the next one and it shows us which one we skipped.

MATTEO COLLINA: Something really cool  we can't really demonstrate this super easily. There's a really nice repo from one of the other TSC members, called Reporters. I put it in the chat.

JASON LENGSTORF: Copy link. Here we go...

MATTEO COLLINA: Okay. Scroll down. You can do this, you can pass these reporters. Now, the important part is reporter/getup. If you open it up, it will probably show a picture of it. Yeah, you will see [Indiscernible] your PR.

JASON LENGSTORF: That's handy.

MATTEO COLLINA: Yeah, it is. I use it all the time.

JASON LENGSTORF: Well, and the fact  so, this is  so, you need the reporter module, but the rest of it is using the builtin 

MATTEO COLLINA: Exactly. You can pass them as a commandline arguments. If you scroll down, you can do "testreporter." You can add when do whatever you need from this.

JASON LENGSTORF: Extremely cool. And so the reporters, themselves  yeah, this is great. And so this also means, then, presumably, you can write a reporter for any destination, like, if you wanted to report errors to your Slack, you could write a reporter for Slack. Whatever, anywhere you wanted to put that information, you have the ability to go and build one of these.

MATTEO COLLINA: Exactly. [Indiscernible] code is very  if you go inside here.

JASON LENGSTORF: Yeah, let's peek at one of these.

MATTEO COLLINA: Do the GitHub one because I played with it so I know. You can just open the index.js.

JASON LENGSTORF: So we've got everything going on. How big is this? 120 lines of code to report to GitHub, which I imagine is one of the more, like, involved use cases because it requires networks requests and API keys.

MATTEO COLLINA: No. It works with changing the output and landing specific comments. If you scroll down, you can see that there is some of those things. It uses the GitHub Core Module. So, if you go up, you can see that it imports a Core Module and it's  yeah. [Indiscernible] and that's what does the trick. But in the end  and then you can see, there's a "for await," this kind of stuff.

JASON LENGSTORF: Okay. I see what's happening here. This is  this is slick. And then, yeah, you add some extra pieces here to grab out the right details, but this is  this is pretty  like, I don't know. Chat, I hope your gears are turning on the types of things that open up with this. You can probably do this with other test runners, as well, but the fact that you don't need the other test runners, you can use Node Test  it's just nice to think about how much project you can build without having to install a bunch of additional projects.

MATTEO COLLINA: Yes, yes, absolutely. So, this is what I wanted to go on. And we didn't talk about Fetch.

JASON LENGSTORF: Because Fetch is guilt in now.

MATTEO COLLINA: Yes. And you can thank me and the rest of the team. Back in 2018  there's a video on YouTube of me. The path of getting this to Core. Last October, we were able to call it stable. So, it took, I don't know...a few years to get there, okay. And, right now, we are still investing a lot of effort in making it faster because it's still slow, from old point of view. But we are working a lot on making it faster, making it better, all sorts of things.
It's great and it just works out of the box so you know how use Fetch, more or less, it works case. We are improving. We're getting there.

JASON LENGSTORF: Extremely cool. So, we are  we are effectively out of time so I'm going to send everybody back to your Twitter if they want to follow along with what you're doing, what you're working on. [Laughter]. You made Fetch happen. [Laughter]. You can go find the Node docs here...and, is there anywhere else you want people to go?

MATTEO COLLINA: To be clear, this was a massive team effort. I laid out the plan and everybody else did the work. I worked on the lowlevel piece to make it happen, the lowlevel API that made it possible, then other people, like [Indiscernible] and Ethan and a lot of others contributed back and get this where it is right now. It's not just me. Absolutely. I'm not trying to  I'm just saying  my basic contribution was, this was the plan. [Laughter]. And, you know, I throw the  built the first version and then everything happened after that.

JASON LENGSTORF: So, where else should people go if they want to dig deeper? Is there a specific article or a resource you'd recommend?

MATTEO COLLINA: On Fetch or what?

JASON LENGSTORF: On modern Node.

MATTEO COLLINA: It is a problem. There isn't much. The website contains a lot of it. Probably still we need a lot of help on how do we communicate this in the best way, in a better way. Okay. Part of me being here, Jason, is for sharing it with others, making it  making it possible  telling people these exist, okay, because, to be honest, a lot of people don't, okay. All the stuff is not there. We are currently thinking of starting an ambassador programs  an ambassador program, for Node, to help us teach people all this new stuff. Okay. Which is not there. A lot of people don't know about it. How can we tell people how to use all of this? Okay.
And of course 

JASON LENGSTORF: And  so, this is a good note to anybody watching. If anybody's out there thinking, I want to write more, I want to create more, I want to make more videos, there's a huge wealth of new information about Node that is not being covered so this is a great way to kind of help push the web forward with your content because if we can make enough content that it starts to take the place of those articles that are being pushed now, that show 10yearold Node code, we can modernize the whole internet together so this is a good opportunity to get out there and build some projects using these new features and write articles about how maybe you don't need the dependencies. You can actually build it with builtin Node modules. Those are really impactful things that you can do right now.

MATTEO COLLINA: Exactly. So, yeah. Like, volunteers. Node.js is built on volunteers. We have no  we have nobody directly funding the work. Okay. There are a lot of volunteers and their companies sponsor their work. Okay. And, but there's no straight on anybody working on this  on the project.
The only person that is working fulltime is helping us on security. We have some money from the [Indiscernible] but only working on security. Very active on the security front. Okay. And as you probably all know, ships a lot of security releases. And, you know, you should upgrade to latest Node. [Laughter]. Pretty please. The world will thank you.
A lot of you still not using that, so, there is  I don't know how to fix it, but a lot of people  you, you're watching, you should upgrade now.

JASON LENGSTORF: Right now. Do it today. [Laughter].

MATTEO COLLINA: You're not updating Node. Your Node is not uptodate. Okay. The numbers tell me that Node  you're not updating Node. So, part of my presentation was, you're not updating Node. So you can  and, that's cool. Okay. So, yeah, that's  that's all of it and thank you for having me, Jason, and thank you, all, everybody, for watching.

JASON LENGSTORF: Yeah, thank you so much for being here, Matteo. One more shoutout to Nx and Netlify. Thank you to Vanessa for doing the live captioning today. While you're checking things out on the site, make sure you go and check out the schedule because we've got so much good stuff coming up. Get over there, check it out. Hit the "like" button. Get on the newsletter. Do all the things. Thank you all, so much, and we will see you next time.

MATTEO COLLINA: Bye, bye, byeeee.

JASON LENGSTORF: Okay. Bye, for real. [Laughter].

Closed captioning and more are made possible by our sponsors: