Live data from Hacker News

Modern Node.js Patterns

kashw1n.com

381–390 of 448 posts

Re: Modern Node.js Patterns

#381

Earlier quoted context omitted.

It was neither a design choice nor a technical limitation. It was a big complicated thing which necessarily involved fiddly internal work and coordination between relatively isolated groups. It got done when someone (Joyee Cheung) actually made the fairly heroic effort to push through all of that. Joyee has a nice post going into details. Reading this gives a much more accurate picture of why things do and don't happ…

Node.js made many decisions that have massive impact on ESM adoption. From forcing extensions and dropping index.js to loaders and complicated package.json "exports". In addition to node.js steamrolling everyone, tc39 keep making are idiotic changes to spec like `deffered import` and `with` syntax changes.

Requiring file extensions and not supporting automatic "index" imports was a requirement from Browsers where you can't just scan a file system and people would be rightfully upset if their browser modules sent 4-10 HEAD requests to find the file it was looking for.

"exports" controls in package.json was something package/library authors had been asking for for a long time even under CJS regimes. ESM gets a lot of blame for the complexity of "exports", because ESM packages were required to use it but CJS was allowed to be optional and grandfathered, but most of the complexity in the format was entirely due to CJS complexity and Node trying to support all the "exports" options already in the wild in CJS packages. Because "barrel" modules (modules full of just `export thing from './thing.js'`) are so much easier to write in ESM I've yet to see an ESM-only project with a complicated "exports". ("exports" is allowed to be as simple as the old main field, just an "index.js", which can just be an easily written "barrel" module).

> tc39 keep making are idiotic changes to spec like `deffered import` and `with` syntax changes

I'm holding judgment on deferred imports until I figure out what use cases it solves, but `with` has been a great addition to `import`. I remember the bad old days of crazy string syntaxes embedded in module names in AMD loaders and Webpack (like the bang delimited nonsense of `json!embed!some-file.json` and `postcss!style-loader!css!sass!some-file.scss`) and how hard it was to debug them at times and how much they tied you to very specific file loaders (clogging your AMD config forever, or locking you to specific versions of Webpack for fear of an upgrade breaking your loader stack). Something like `import someJson from 'some-file.json' with { type: 'json', webpackEmbed: true }` is such a huge improvement over that alone. The fact that it is also a single syntax that looks mostly like normal JS objects for other very useful metadata attribute tools like bringing integrity checks to ESM imports without an importmap is also great.

Re: Modern Node.js Patterns

#382
post #76

Earlier quoted context omitted.

Tangential, but thought I'd share since validation and API calls go hand-in-hand: I'm personally a fan of using `ts-rest` for the entire stack since it's the leanest of all the compile + runtime zod/json schema-based validation sets of libraries out there. It lets you plug in whatever HTTP client you want (personally, I use bun, or fastify in a node env). The added overhead is totally worth it (for me, anyway) for sh…

I've been impressed with Hono's zod Validator [1] and the type-safe "RPC" clients [2] you can get from it. Most of my usage of Hono has been in Deno projects, but it seems like it has good support on Node and Bun, too. [1] https://hono.dev/docs/guides/validation#zod-validator-middle... [2] https://hono.dev/docs/guides/rpc#client

Agreed. Hono has been great for my usage, and very portable.

Re: Modern Node.js Patterns

#383

Be honest. How much of this article did you write, and how much did ChatGPT write?

Be honest. Did you write this comment with an LLM?

Why should it matter beyond correctness of the content, which you and the author need to evaluate either way.

Personally, I'm exhausted with this sentiment. There's no value in questioning how something gets written, only the output matters. Otherwise we'd be asking the same about pencils, typewriters, dictionaries and spellcheck in some pointless persuit of purity.

Re: Modern Node.js Patterns

#384
post #318
post #10

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!

I tried node:test and I feel this is very useful for tiny projects and library authors who need to cut down on 3rd party dependencies, but it's just too barebones for larger apps and node:assert is a bit of a toy, so at a minimum you want to pull in a more full-fledged assertion library. vitest "just works", however, and paves over a lot of TypeScript config malarkey. Jest collapsed under its own weight.

As someone who eschewed jest and others for years for the simplicity of mocha, I still appreciate the design decision of mocha to keep the assertions library separate from the test harness. Which is to point out that chai [1] is still a great assertions library and only an assertions library.

(I haven't had much problem with TypeScript config in node:test projects, but partly because "type": "module" and using various versions of "erasableSyntaxOnly" and its strict-flag and linter predecessors, some of which were good ideas in ancient mocha testing, too.)

[1] https://www.chaijs.com/

Re: Modern Node.js Patterns

#385
post #242
post #113

Whoa, I didn't know about this: # Run with restricted file system access node --experimental-permission \ --allow-fs-read=./data --allow-fs-write=./logs app.js # Network restrictions node --experimental-permission \ --allow-net=api.example.com app.js Looks like they were inspired by Deno. That's an excellent feature. https://docs.deno.com/runtime/fundamentals/security/#permiss...

I very much dislike such features in a runtime or app. The "proper" place to solve this, is in the OS. Where it has been solved, including all the inevitable corner cases, already. Why reinvent this wheel, adding complexity, bug-surface, maintenance burden and whatnot to your project? What problem dies it solve that hasn't been solved by other people?

The pragmatic reason is that the runtime should have more permissions than the code, eg in node require('fs') likely read files in system folders

Re: Modern Node.js Patterns

#386
post #110

Earlier quoted context omitted.

I learned quite a few new things from this, I don't really care if OP filtered it through an LLM before publishing it

Same, but, I'm struggling with the idea that even if I learn things I haven't before, at the limit, it'd be annoying if we gave writing like this a free pass continuously - I'd argue filtered might not be the right word - I'd be fine with net reduction. Theres something bad about adding fluff (how many game changers were there?) An alternative framing I've been thinking about is, there's clearly something bad when yo…

You can critique the writing without calling into question how it was written. Speculation on the tools used to write it serves no purpose beyond making a, possibly unfounded, value judgement against the writer.

https://hbr.org/2025/08/research-the-hidden-penalty-of-using...

Re: Modern Node.js Patterns

#387
post #108

Why bother with node when bun is a much better alternative for new projects?

I haven't used it for a few months but in my experience, its package/monorepo management features suck compared to pnpm (dependencies leak between monorepo packages, the command line is buggy, etc), bun --bun is stupid, build scripts for packages routinely blow up since they use node so i end up needing to have both node and bun present for installs to work, packages routinely crash because they're not bun-compatible…

We’ve made a lot of progress on bun install over the last few months:

- isolated, pnpm-style symlink installs for node_modules

- catalogs

- yarn.lock support (later today)

- bun audit

- bun update —interactive

- bun why helps find why a package is installed

- bun info

- bun pm pkg get

- bun pm version (for bumping)

We will also support pnpm lockfile migration next week. To do that, we’re writing a YAML parser. This will also unlock importing YAML files in JavaScript at runtime.

Re: Modern Node.js Patterns

#388
post #317

Earlier quoted context omitted.

Yes. Also CommonJS does not support tree shaking.

Nor does ESM if you import * as. Plus I believe it can be made to support tree shaking Edit: the proof my point reside in the many libraries which have an open issue because, even if ESM, they don't support tree shaking

`import * as` is still treeshakeable and Browsers will do it in-memory as the imports form weak proxies.

Bundlers can treeshake it, it is just harder to do, and so it hasn't always been a priority feature. esbuild especially in the last few years has done a lot of work to treeshake `import * as` in many more scenarios than before. Sure it isn't treeshaking "all" scenarios yet, but it's still getting better.

Re: Modern Node.js Patterns

#389
post #266

Earlier quoted context omitted.

Sounds like there's space for an axios-like library built on top of fetch.

Like axios can do it if you specify the fetch backend, it just won't do the .json() asynchronously.

I'm actually not a big fan of the async .json from fetch, because when it fails (because "not json"), then you can't peak at the text instead. Of course, you can clone the response, apparently, and then read text from the clone... and if you're wrapping for some other handling, it isn't too bad.

Re: Modern Node.js Patterns

#390
post #385
post #242

Earlier quoted context omitted.

I very much dislike such features in a runtime or app. The "proper" place to solve this, is in the OS. Where it has been solved, including all the inevitable corner cases, already. Why reinvent this wheel, adding complexity, bug-surface, maintenance burden and whatnot to your project? What problem dies it solve that hasn't been solved by other people?

The pragmatic reason is that the runtime should have more permissions than the code, eg in node require('fs') likely read files in system folders

Not necessarily, in selinux for example you would configure a domain for the "main process" which can transition into a lower permission domain for "app" code.
Post reply on HN