Modern Node.js Patterns

111 eustoria 30 8/3/2025, 7:16:18 PM kashw1n.com ↗

Comments (30)

amclennon · 48s ago
Some good stuff in here. I had no idea about AsyncIterators before this article, but I've done similar things with generators in the past.

A couple of things seem borrowed from Bun (unless I didn't know about them before?). This seems to be the silver lining from the constant churn in the Javascript ecosystem

farkin88 · 30m ago
The killer upgrade here isn’t ESM. It’s Node baking fetch + AbortController into core. Dropping axios/node-fetch trimmed my Lambda bundle and shaved about 100 ms off cold-start latency. If you’re still npm i axios out of habit, 2025 Node is your cue to drop the training wheels.
yawnxyz · 17m ago
node fetch is WAY better than axios (easier to use/understand, simpler); didn't really know people were still using axios
Raed667 · 8m ago
I do miss the axios extensions tho, it was very easy to add rate-limits, throttling, retry strategies, cache, logging ..

You can obviously do that with fetch but it is more fragmented and more boilerplate

azangru · 7m ago
Matteo Collina says that the node fetch under the hood is the fetch from the undici node client [0]; and that also, because it needs to generate WHATWG web streams, it is inherently slower than the alternative — undici request [1].

[0] - https://www.youtube.com/watch?v=cIyiDDts0lo

[1] - https://blog.platformatic.dev/http-fundamentals-understandin...

rco8786 · 7m ago
I've been away from the node ecosystem for quite some time. A lot of really neat stuff in here.

Hard to imagine that this wasn't due to competition in the space. With Deno and Bun trying to eat up some of the Node market in the past several years, seems like the Node dev got kicked into high gear.

gabrielpoca118 · 38m ago
Don’t forget the native typescript transpiler which reduces the complexity a lot for those using TS
mmcnl · 18m ago
Exactly. You don't even need --experimental-strip-types anymore.
tyleo · 50m ago
This is great. I learned several things reading this that I can immediately apply to my small personal projects.

1. Node has built in test support now: looks like I can drop jest!

2. Node has built in watch support now: looks like I can drop nodemon!

yawnxyz · 18m ago
I feel like node and deno conventions are somehow merging (which is a good thing)
keysdev · 1h ago
About time! The whole dragging the feet on ESM adoption is insane. The npm are still stuck on commonjs is quite a lot. In some way glad jsr came along.
lvl155 · 1h ago
Thank you for this. Very helpful as I was just starting to dig into node for first time in a few years.
kfuse · 27m ago
Node now has limited supports for Typescript and has SQLite built in, so it becomes really good for small/personal web oriented projects.
chickenzzzzu · 1h ago
Yet more architecture astronaut behavior by people who really should just be focusing on ifs, fors, arrays, and functions.
triyambakam · 1h ago
Architecture astronaut is a term I hadn't heard but can appreciate. However I fail to see that here. It's a fair overview of newish Node features... Haven't touched Node in a few years so kinda useful.
chickenzzzzu · 58m ago
It's a good one with some history and growing public knowledge now. I'd encourage a deep dive, it goes all the way back to at least CPP and small talk.

While I can see some arguments for "we need good tools like Node so that we can more easily write actual applications that solve actual business problems", this seems to me to be the opposite.

All I should ever have to do to import a bunch of functions from a file is

"import * from './path'"

anything more than that is a solution in search of a problem

MrJohz · 27m ago
Isn't that exactly the syntax being recommended? Could you explain what exactly in the article is a solution in search of a problem?
flufluflufluffy · 56m ago
what? This is an overview of modern features provided in a programming language runtime. Are you saying the author shouldn’t be wasting their time writing about them and should be writing for loops instead? Or are you saying the core devs of a language runtime shouldn’t be focused on architecture and should instead be writing for loops?
programmarchy · 1h ago
One of the core things Node.js got right was streams. (Anyone remember substack’s presentation “Thinking in streams”?) It’s good to see them continue to push that forward.
chickenzzzzu · 56m ago
Why? Why is a stream better than an array? Why is the concept of a realtime loop and for looping through a buffer not sufficient?
cluckindan · 1m ago
Streams have backpressure, making it possible for downstream to tell upstream to throttle their streaming. This avoids many issues related to queuing theory.

That also happens automatically, it is abstracted away from the users of streams.

bblaylock · 37m ago
I think there are several reasons. First, the abstraction of a stream of data is useful when a program does more than process a single realtime loop. For example, adding a timeout to a stream of data, switching from one stream processor to another, splitting a stream into two streams or joining two streams into one, and generally all of the patterns that one finds in the Observable pattern, in unix pipes, and more generally event based systems, are modelled better in push and pull based streams than they are in a real time tight loop. Second, for the same reason that looping through an array using map or forEach methods is often favored over a for loop and for loops are often favored over while loops and while loops are favored over goto statements. Which is that it reduces the amount of human managed control flow bookkeeping, which is precisely where humans tend to introduce logic errors. And lastly, because it almost always takes less human effort to write and maintain stream processing code than it does to write and maintain a real time loop against a buffer.

Hopefully this helps! :D

dwb · 34m ago
A stream is not necessarily always better than an array, of course it depends on the situation. They are different things. But if you find yourself with a flow of data that you don't want to buffer entirely in memory before you process it and send it elsewhere, a stream-like abstraction can be very helpful.