Live data from Hacker News

Modern Node.js Patterns

kashw1n.com

191–200 of 448 posts

Re: Modern Node.js Patterns

#191
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…

Type safety for API calls is huge. I haven't used ts-rest but the compile-time validation approach sounds solid. Way better than runtime surprises. How's the experience in practice? Do you find the schema definition overhead worth it or does it feel heavy for simpler endpoints?

The schema definition is more efficient than writing input validation from scratch anyway so it’s completely win/win unless you want to throw caution to the wind and not do any validation

Re: Modern Node.js Patterns

#193
post #108

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

because bun is written in a language that isn't even stable (zig) and uses webkit. None of the developer niceties will cover that up. I also don't know if they'll be able to monetize, which means it might die if funding dries up.

Re: Modern Node.js Patterns

#194
post #183
post #139

Earlier quoted context omitted.

How do you supply the schema on the other side? I found that keeping the frontend & backend in sync was a challenge so I wrote a script that reads the schemas from the backend and generated an API file in the frontend.

There are a few ways, but I believe SSOT (single source of truth) is key, as others basically said. Some ways: 1. Shared TypeScript types 2. tRPC/ts-rest style: Automagic client w/ compile+runtime type safety 3. RTK (redux toolkit) query style: codegen'd frontend client I personally I prefer #3 for its explicitness - you can actually review the code it generates for a new/changed endpoint. It does come w/ downside of…

What is a validation quirk that would happen when using server side Zod schemas that somehow doesn’t happen with a codegened client?

Re: Modern Node.js Patterns

#195
post #151

Earlier quoted context omitted.

16 years after launch, the JS runtime centered around network requests now supports network requests out of the box.

Obviously it supported network requests, the fetch api didn't even exist back then, and XMLHttpRequest which was the standard at the time is insane.

Insane but worked well. At least we could get download progress.

Re: Modern Node.js Patterns

#196
post #78

Earlier quoted context omitted.

I never really liked the syntax of fetch and the need to await for the response.json, implementing additional error handling - async function fetchDataWithAxios() { try { const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1'); console.log('Axios Data:', response.data); } catch (error) { console.error('Axios Error:', error); } } async function fetchDataWithFetch() { try { const response = awa…

I usually write it like: const data = (await fetch(url)).then(r => r.json()) But it's very easy obviously to wrap the syntax into whatever ergonomics you like.

why not?

    const data = await (await fetch(url)).json()

Re: Modern Node.js Patterns

#197
post #78

Earlier quoted context omitted.

I never really liked the syntax of fetch and the need to await for the response.json, implementing additional error handling - async function fetchDataWithAxios() { try { const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1'); console.log('Axios Data:', response.data); } catch (error) { console.error('Axios Error:', error); } } async function fetchDataWithFetch() { try { const response = awa…

Yeah, that's the classic bundle size vs DX trade-off. Fetch definitely requires more boilerplate. The manual response.ok check and double await is annoying. For Lambda where I'm optimizing for cold starts, I'll deal with it, but for regular app dev where bundle size matters less, axios's cleaner API probably wins for me.

You’re shooting yourself in the foot if you put naked fetch calls all over the place in your own client SDK though. Or at least going to extra trouble for no benefit

Re: Modern Node.js Patterns

#198
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!

Eh, the Node test stuff is pretty crappy, and the Node people aren't interested in improving it. Try it for a few weeks before diving headfirst into it, and you'll see what I mean (and then if you go to file about those issues, you'll see the Node team not care).

I just looked at the documentation and it seems there's some pretty robust mocking and even custom test reporters. Definitely sounds like a great addition. As you suggest, I'll temper my enthusiasm until I actually try it out.

Re: Modern Node.js Patterns

#199

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.

Those... are not mutually exclusive as killer upgrade. No longer having to use a nonsense CJS syntax is absolutely also a huge deal. Web parity was "always" going to happen, but the refusal to add ESM support, and then when they finally did, the refusal to have a transition plan for making ESM the default, and CJS the fallback, has been absolutely grating for the last many years.

Especially since it seems perfectly possible to support both simultaneously. Bun does it. If there's an edge case, I still haven't hit it.

Re: Modern Node.js Patterns

#200

Earlier quoted context omitted.

Why would you want to do either of those?

Both are very common Typescript patterns.

Importing without extensions is not a TypeScript thing at all. Node introduced it at the beginning and then stopped when implementing ESM. Being strict is a feature.

What's true is that they "support TS" but require .ts extensions, which was never even allowed until Node added "TS support". That part is insane.

TS only ever accepted .js and officially rejected support for .ts appearing in imports. Then came Node and strong-armed them into it.

Post reply on HN